Consider this code example:
char c = 0xff;
char mask = 0xfe;
switch ((unsigned)(c & mask)) {
case -2: /* do task 1 */ break;
default: /* do task 2 */
}
Let us assume that CHAR_BIT = 8 and the implementation defined assignment to c and mask is via interpretation of the bit patterns: 11111111 and 11111110, and negative zeros are allowed. The behaviour of this code is therefore:
if char is signed and implementation uses 2's complement, c = -1, mask = -2, c & mask = -2, (unsigned)(c & mask) = UINT_MAX - 1
.
if char is signed and implementation uses 1's complement, c = 0, mask = -1, c & mask = 0, (unsigned)(c & mask) = 0
.
c
is zero and not negative zero because C does not allow creation of negative zero via an assignment.
if char is signed and implementation uses signed magnitude, c = -127, mask = -126, c & mask = -126, (unsigned)(c & mask) = UINT_MAX - 125
if char is unsigned c = 255, mask = 254, c & mask = 254, (unsigned)(c & mask) = 254
The case constant -2
is converted to the same type as the controlling expression, so the value is UINT_MAX - 1
. Hence it would only match if char is signed and implementation uses 2's complement.
Is this correct according to the C standard or are there additional assumptions that needs to be added?
Not really. If
char
is signed and 8-bit (ie.CHAR_MAX
is less than 255), then the lineis implementation-defined. It might do what you say, but it might not.
The C standard 6.3.1.3: