考虑以下代码示例:
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
案例常量-2
转换为与控制表达式相同的类型,因此值为UINT_MAX - 1
。因此,只有在签名char并且实现使用2的补码时才会匹配。
根据C标准,这是正确的还是需要添加其他假设?
答案 0 :(得分:1)
根据C标准,这是否正确
不是真的。如果char
已签名且8位(即CHAR_MAX
小于255),则该行
char c = 0xff;
是实现定义的。它可能会按你说的做,但可能没有。
C标准6.3.1.3:
否则,新类型已签名且值无法在其中表示;无论是 结果是实现定义或实现定义的信号。