4

考虑这个代码示例:

char c = 0xff;
char mask = 0xfe;
switch ((unsigned)(c & mask)) {
case -2: /* do task 1 */ break;
default:   /* do task 2 */
}

让我们假设 CHAR_BIT = 8 并且实现定义的对 c 和掩码的赋值是通过位模式的解释:11111111 和 11111110,并且允许负零。因此,此代码的行为是:

如果 char 已签名并且实现使用 2 的补码,c = -1, mask = -2, c & mask = -2, (unsigned)(c & mask) = UINT_MAX - 1.

如果 char 已签名并且实现使用 1 的补码,c = 0, mask = -1, c & mask = 0, (unsigned)(c & mask) = 0. c是零而不是负零,因为 C 不允许通过赋值创建负零。

如果 char 是有符号的并且实现使用有符号的幅度,c = -127, mask = -126, c & mask = -126, (unsigned)(c & mask) = UINT_MAX - 125

如果 char 是无符号的c = 255, mask = 254, c & mask = 254, (unsigned)(c & mask) = 254

case 常量-2被转换为与控制表达式相同的类型,因此值为UINT_MAX - 1。因此,只有在 char 被签名并且实现使用 2 的补码时,它才会匹配。

根据 C 标准这是正确的还是需要添加其他假设?

4

1 回答 1

1

根据 C 标准,这是否正确

并不真地。如果char是有符号且 8 位(即CHAR_MAX小于 255),则该行

char c = 0xff;

是实现定义的。它可能会按您说的做,但可能不会。

C标准6.3.1.3:

否则,新类型是有符号的,值不能在其中表示;结果要么是实现定义的,要么是产生实现定义的信号。

于 2011-11-09T09:39:37.017 回答