5

根据“为什么在 offsetof() 中减去空指针?”中的响应。(以及我对 K&R 的阅读),C 标准不需要(size_t)((char *)0) == 0. 尽管如此,我从未见过将空指针转换为整数类型的情况会评估为其他任何东西。

如果有编译器或场景 where (size_t)((char *)0) != 0,它是什么?

4

4 回答 4

4

好吧,如您所知,给定类型的空指针的物理表示不一定是全零位模式。当您强制将指针(任何指针)值转换为整数类型时,结果是实现定义的,但通常(这就是意图)指针的数值 - 数字地址 - 如果可能的话保持不变。这意味着,如果在给定平台上,类型的空指针char *0xBAADF00D模式表示(例如),则上述表达式的计算结果为0xBAADF00D,而不是零。当然,为此您需要一个具有非零空指针的平台。我个人从未使用过这样的平台,尽管我听说过很多像这样的真实平台(比如,在嵌入式平台领域,这并不罕见)。

此外,作为附加说明,不同类型的空指针值可以具有不同的物理表示,这意味着理论上您可以从 和 获得不同(size_t) ((int *) 0)(size_t) ((char *) 0)(size_t) ((double *) 0)。但这将是一个相当奇特的情况,尽管从抽象 C 语言的角度来看是完全可能的。

PS 阅读此处(C 常见问题解答)以获取具有非零空指针的实际平台的一些示例。

于 2010-04-05T22:28:50.423 回答
1

C 标准对空指针运行时表示的唯一要求是(6.3.2.3/3“指针”):

...生成的指针,称为空指针,保证与指向任何对象或函数的指针不相等。将空指针转换为另一种指针类型会产生该类型的空指针。

任何两个空指针应该比较相等。

不过,你的问题很有趣。就个人而言,我不知道不使用运行时值 0 来表示空指针的平台。但是,标准不需要它,所以如果您可以避免代码中的假设,为什么不呢?

我也对任何知道使用非零运行时值作为空指针的系统的人感兴趣。

于 2010-04-05T22:29:04.917 回答
1

C99 标准规定,当您将整数值转换0为指针时,它将变为 NULL 指针。((char*)0)NULL 指针也是如此。NULL 指针不需要具有实际的二进制表示0。例如,它可以是0x12345678

C 标准进一步指出,当您将 NULL 指针转换为整数常量时,结果是“实现定义的”。实际上,编译器所做的只是将指针的数值转换为相应的整数值,正如 AndreyT 所说。所以在上面的例子中,整数值最终可能是0x12345678,尽管从技术上讲它可以是任何东西(即编译器被允许说“将 NULL 指针转换回整数值导致值0xDEADBEEF”)。请注意,这意味着即使在 NULL 指针具有 value 的平台上0,编译器也可以在转换时将其转换为任意整数值。然而,实际上,没有编译器会这样做,因为这太疯狂了。

所以,是的,C 标准允许做很多事情。实际上,您可能使用的任何平台都将表示 NULL 指针,0并将 NULL 指针转换为整数值将导致0. 在此处(第 1.14 节)查看不0用于 NULL 指针的(晦涩)架构的一些异常列表。

于 2010-04-05T22:45:07.763 回答
0

这不适用于char*甚至 C,但是索引到数组的智能指针类可能会选择表示NULL为,-1因为0它是有效的数组索引。

考虑到 的习惯用法memset( my_new_struct, 0, sizeof my_new_struct );,即使是以调试为中心的系统也不太可能打破这种身份。

于 2010-04-05T22:34:47.817 回答