c++ - C 和 C++ 标准是否暗示地址空间中的特殊值必须仅存在以表示空指针的值?

标签 c++ c language-lawyer systems-programming

根据 this question 的讨论关于 C 和 C++ 中的空指针,我想在这里分开结束问题。

如果可以从 C 和 C++ 标准(答案可以同时针对这两个标准)推断出取消引用一个指针变量,其值等于 nullptr (或(void *)0)值是未定义的行为,是否暗示这些语言要求地址空间中的一个特殊值dead,意味着它除了代表nullptr的作用外无法使用?如果系统在等于 nullptr 的相同地址处有一个真正有用的函数或数据结构怎么办? ?这永远不会发生,因为编译器的编写者有责任为编译器编译到的每个系统找出一个不冲突的空指针值吗?或者需要访问此类函数或数据结构的程序员是否应该满足于在“未定义行为模式”下编程以实现其意图?

这看起来像是模糊了编译器和计算机系统的角色界限。我会问这样做是否正确,但我想这里没有这个空间。

This blog post digs about tackling the problem situation

最佳答案

这取决于短语“地址空间”的含义。 C 标准非正式地使用了这个短语,但没有定义它的含义。

对于每种指针类型,都必须有一个(空指针)比较不等于指向任何对象或函数的指针。这意味着,例如,如果指针类型为 32 位宽,则该类型最多可以有 232-1 个有效的非空值。如果某些地址具有不止一种表示,或者如果不是所有表示都对应于有效地址,则可能会更少。

因此,如果您将“地址空间”定义为覆盖 2N 个不同的地址,其中 N 是指针的位宽度,那么是的,这些值之一必须保留为 null指针值。

另一方面,如果“地址空间”比这更窄(例如,典型的 64 位系统实际上不能访问 264 个不同的内存位置),那么保留值因为空指针很容易位于“地址空间”之外。

一些注意事项:

  • 空指针的表示可能是也可能不是全零。
  • 并非所有指针类型都必须具有相同的大小。
  • 并非所有指针类型都必须对空指针使用相同的表示形式。

在大多数现代实现中,所有指针类型都是相同的大小,并且都将空指针表示为全零,但是有充分的理由,例如,使函数指针更宽比对象指针更宽,或者使 void*int* 宽,或者对空指针使用除全零位之外的表示。

此答案基于 C 标准。其中大部分也适用于 C++。 (一个区别是 C++ 具有指向成员的指针类型,通常比普通指针更宽。)

关于c++ - C 和 C++ 标准是否暗示地址空间中的特殊值必须仅存在以表示空指针的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28574069/

相关文章:

c++ - 给定一个用三角形镶嵌的面片,如何修改它的新顶点位置?

C++ 钩子(Hook)进程和显示状态

c++ - 这里有更多 C++ 中未定义的行为,很抱歉这个问题,但又是 UB

c++ - 在 C++11 lambda 中按引用捕获引用

c - 如何将值保存到已分配内存的指针?

c++ - 为什么 lambda 会删除 cv 和 ref?

c++ - 空引用如何导致代码为 0xc0000005 的 SEH 异常?

c++ - 按单个字符比较两个字符串 C++

objective-c - (Obj-)C 中的 BEDMAS 优先级?

c - malloc 中的内存泄漏?