(size_t)((char *)0) 的计算结果是否不等于 0?

发布于 2024-08-27 14:09:45 字数 292 浏览 5 评论 0原文

根据“为什么在offsetof()中减去空指针?”中的回复(以及我对 K&R 的阅读),C 标准不要求 (size_t)((char *)0) == 0。不过,我从未见过将空指针转换为整数类型会计算出其他值的情况。

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

According to the responses in "Why subtract null pointer in offsetof()?" (and my reading of K&R), the C standard doesn't require that (size_t)((char *)0) == 0. Still, I've never seen a situation where casting a null pointer to an integer type evaluates to anything else.

If there is a compiler or scenario where (size_t)((char *)0) != 0, what is it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我早已燃尽 2024-09-03 14:09:45

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

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

PS 请阅读此处(C 常见问题解答),了解具有非零 null 的实际平台的一些示例指针。

Well, as you know, the physical representation of null pointer of a given type is not necessarily all-zero bit pattern. When you forcefully convert a pointer (any pointer) value to integer type, the result is implementation defined, but normally (and that's the intent) the numerical value of the pointer - the numerical address - remains unchanged, if possible. This means that if on a given platform a null pointer of type char * is represented by 0xBAADF00D pattern (for example), the above expression will evaluate to 0xBAADF00D, and not to zero. Of course, for that you'd need a platform with non-zero null-pointers. I personally never worked with such platforms, although I heard about a number of real platforms like that out there (like, in the realm of embedded platforms it is not something unusual).

Moreover, as an additional note, null pointer values of different types can have different physical representations, meaning that in theory you can get different values from (size_t) ((int *) 0), (size_t) ((char *) 0) and (size_t) ((double *) 0). But that would be a rather exotic situation, albeit perfectly possible from the point of view of abstract C language.

P.S. Read here (C FAQ) for some examples of actual platforms with non-zero null pointers.

过潦 2024-09-03 14:09:45

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

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

任意两个空指针比较相等。

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

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

The only thing that the C standard requires of a null pointer's runtime representation is (6.3.2.3/3 "Pointers"):

...the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function. Conversion of a null pointer to another pointer type yields a null pointer of that type.

Any two null pointers shall compare equal.

Your question is an interesting one, though. Personally, I'm unaware of a platform that doesn't use the runtime value 0 to represent a null pointer. However, the standard doesn't require it, so if you can avoid the assumption in your code, why not?

I'd also be interested in anyone who knows of a system that uses a non-zero runtime value for a null pointer.

哑剧 2024-09-03 14:09:45

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

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

所以,是的,C 标准允许很多事情。实际上,您可能使用的任何平台都将 NULL 指针表示为 0,并将 NULL 指针转换为整数值将导致 0。请查看此处(第 1.14 节),获取以下列表:一些(模糊的)体系结构的例外,它们不使用 0 作为 NULL 指针。

The C99 standard says that when you convert an integer value 0 to a pointer, it becomes a NULL pointer. So ((char*)0) is a NULL pointer. A NULL pointer need not have an actual binary representation of 0. It can be, for example 0x12345678.

The C standard further states that when you convert a NULL pointer to an integer constant, the result is "implementation-defined". In reality, what compilers do is simply cast the use the numerical value of the pointer to the corresponding integer value, as AndreyT said. So in the example above, the integer value might end up being 0x12345678, though technically it could be anything at all (ie. the compiler is allowed to say "converting a NULL pointer back to an integer value results in value 0xDEADBEEF"). Note that this means that even on platforms where the NULL pointer has the value 0, the compiler is allowed to convert it to an arbitrary integer value upon conversion. In reality, however, no compilers do that because it would be fairly insane.

So, yes, the C standard allows a lot of things. In reality, any platform you are likely to work on will represent a NULL pointer as 0 and converting a NULL pointer to an integer value will result in 0. Look here (section 1.14) for a list of some exceptions of (obscure) architectures which do not use 0 for a NULL pointer.

泪意 2024-09-03 14:09:45

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

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

This doesn't apply to char* or even C, but a smart pointer class which indexes into an array might choose to represent NULL as -1 because 0 is a valid array index.

Considering the idiom of memset( my_new_struct, 0, sizeof my_new_struct );, even a debugging-centric system is unlikely to break that identity.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文