【问题标题】:The C standard's word on the switch statementC 标准关于 switch 语句的语句
【发布时间】:2011-11-09 09:15:13
【问题描述】:

考虑这个代码示例:

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) = 0c 是零而不是负零,因为 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 标准这是正确的还是需要添加其他假设?

【问题讨论】:

    标签: c switch-statement bit standards representation


    【解决方案1】:

    根据 C 标准,这是否正确

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

    char c = 0xff;
    

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

    C 标准 6.3.1.3:

    否则,新类型是有符号的,值不能在其中表示;无论是 结果是实现定义的或引发了实现定义的信号。

    【讨论】:

    • 我的印象是这是实现定义的行为,而不是未定义的行为
    • 为什么 0xff 是未定义的?如果 char 已签名,则为 -1。
    • @Jim 我会说这是因为 0xff 溢出了一个签名字符
    • 0xff 是十六进制值,而不是有符号/无符号值。根据分配给它的类型,它可以表示有符号/无符号值。 (否则如何将 -1 分配为十六进制值?)
    • @JimBuck:不正确,0xff 与 255 相同。在 C 中没有“十六进制值”,只有数字。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-24
    • 2012-05-14
    • 2018-01-11
    • 1970-01-01
    • 2012-09-04
    • 2011-11-27
    • 1970-01-01
    相关资源
    最近更新 更多