Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: reworked example a little bit

...

Noncompliant Code Example

In this pedagogical noncompliant code example, on implementations where sizeof(unsigned long) == sizeof(unsigned int), each bit of x is correctly flipped using mask.However, on implementations where sizeof(unsigned long) > sizeof(unsigned int), mask will have leading zeros, e.g. mask == 0x00000000FFFFFFFF. Then, only the lower-order bits of x will be flippedthe flipbits() function complements the value stored in x by performing a bitwise exclusive OR against a mask with all bits set to 1. For implementations where unsigned long is represented by a 32 bit value, each bit of x is correctly complemented.

Code Block
bgColor#FFCCCC
// (Incorrect) Set all bits in mask to one.
const unsigned long mask = 0xFFFFFFFF;

unsigned long flipbits(unsigned long x) {
  return x ^ mask;
}

However, on implementations where values of type unsigned long are represented by greater than 32 bits mask has leading zeros. For example, on implementations where values of type unsigned long are 64 bits long, mask is assigned the value 0x00000000FFFFFFFF. Consequently, only the lower-order bits of x are complemented.

Compliant Solution (-1)

In this compliant solution, the integer constant -1 is used to set all bits in mask to one. The integer constant -1 is of type signed int. Because -1 cannot be represented by a variable of type unsigned long, so -1 it is converted to a representable number according to the rule in Section 6.3.1.3, Paragraph 2 of the C99 standard,

...

For unsigned integer types other than unsigned char, the bits of the object representation shall be divided into two groups: value bits and padding bits (there need not be any of the latter). If there are N value bits, each bit shall represent a different power of 2 between 1 and 2N ? 1 , so that objects of that type shall be capable of representing values from 0 to 2N ? 1 using a pure binary representation; this shall be known as the value representation. The values of any padding bits are unspecified.

...

By the same reasoning, -1 is suitable for setting all bits to one of any unsigned integer variable. Section 6.2.6.1, Paragraph 3 guarantees the same results for unsigned char,

Values stored in unsigned bit-fields and objects of type unsigned char shall be represented using a pure binary notation.

...

Code Block
bgColor#CCCCFF
// (Correct) Set all bits in mask to one.
const unsigned long mask = -1;

unsigned long flipbits(unsigned long x) {
  return x ^ mask;
}

...