代码之家  ›  专栏  ›  技术社区  ›  chqrlie

所有位0都可以是整数的陷阱表示吗?

  •  2
  • chqrlie  · 技术社区  · 7 年前

    通常假设将对象初始化为所有位0是将其所有成员设置为的一种简单方法 0 . 该标准不保证非整数类型的这一点,因为:

    • 所有零位可能不是指针的有效表示,即使是空指针,尽管所有常见的现代系统都使用这种表示。
    • 所有零位可能不是浮点数的合法表示,尽管它在符合IEEE的系统上。

    整数呢?以下代码是否已完全定义:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main(void) {
        int *p = calloc(sizeof(*p), 1);
        if (p) {
            printf("%d\n", *p);
            memset(p, 0, sizeof(*p));
            printf("%d\n", *p);
            free(p);
        }
        return 0;
    }
    
    2 回复  |  直到 7 年前
        1
  •  13
  •   Eugene Sh.    7 年前

    从…起 C Standard, 6.2.6.2, Integer Types

    对于任何整数类型,所有位为零的对象表示应为该类型中值零的表示。

        2
  •  3
  •   Lundin    7 年前

    陷阱表示的定义为C11 6.2.6.1/5:

    某些对象表示不需要表示对象类型的值。如果存储了 对象的值具有这样的表示,并由一个左值表达式读取,该表达式执行以下操作: 通过一个左值表达式修改对象的全部或任何部分的副作用 没有字符类型,行为未定义。50)这种陈述称为 陷阱表示。

    这意味着陷阱表示必须是无效值。

    int 是有效值,因此陷阱表示不可能。

    0xFFFFFFFF (假设32位int)陷阱表示,如果不支持负零。类似地,在一个虚构的符号幅度系统上,值 0x80000000 可以用作陷阱表示。

    在更为疯狂的虚构系统上,整数可能有填充位,然后这些填充位可以用于保存陷阱表示。

    在任何情况下,二进制表示0始终是一个值。许多C标准都依赖于此,例如具有静态存储持续时间的对象初始化、calloc()函数、结构中填充字节的值等。在所有这些中,结果不应是陷阱表示。

    请注意,如果你不是一个虚构系统的程序员,这一切都无关紧要。可能存在一些奇怪的实验性计算机,这是一件事。你甚至可能找到一个还活着的人,他可以告诉你关于他们的事情。

    如果您的设计是为了与这些异国情调的、很可能是虚构的系统兼容,那么您应该详细记录为什么您的产品需要这种兼容性。因为你的老板可能想知道为什么你要花很多时间设计与现实世界中并不存在的计算机的兼容性。