C和C++标准是否意味着地址空间中的特殊值必须仅存在才能表示空指针的值?

pep*_*ico 0 c c++ systems-programming language-lawyer

在关于C和C++中的空指针的这个问题的讨论之后,我想在这里分开结束问题.

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

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

这篇博文详细介绍了解决问题的情况

Kei*_*son 6

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

对于每个指针类型,必须有一个(空指针),它将不等于指向任何对象或函数的指针.这意味着,例如,如果指针类型是32位宽,那么该类型的有效非空值最多可以是2 32 -1.如果某些地址具有多个表示,或者如果不是所有表示都对应于有效地址,则可能少于此.

因此,如果您定义"地址空间"以覆盖2 N个不同的地址,其中N是指针的位宽,则是,其中一个值必须保留为空指针值.

另一方面,如果"地址空间"比那个窄(例如,典型的64位系统实际上不能访问2 64个不同的存储器位置),那么保留为空指针的值可以很容易地在"地址空间".

有些事情需要注意:

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

在大多数现代实现中,所有指针类型都是相同的大小,并且所有指针都表示空指针作为全位零,但是有正当理由,例如,使函数指针比对象指针void*更宽,或者使得更宽int*,或者对于空指针,使用除了all-bits-zero之外的表示.

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

  • @pepper_chico:只要编写可移植代码,它就不会损害可移植性.编写良好的代码*不关心*如何表示空指针. (2认同)
  • @pepper_chico,我不明白你的编译器实现细节,使*语言*不那么便携.*当然*编译器不可移植 - 将可移植程序转换为非便携式机器专用程序集也是如此.编译器应该知道每台不同机器的每个小怪癖.它的工作是知道*application*程序员不必这样做. (2认同)