pep*_*ico 0 c c++ systems-programming language-lawyer
在关于C和C++中的空指针的这个问题的讨论之后,我想在这里分开结束问题.
如果可以从C和C++标准推断(答案可以针对两个标准),取消引用其值等于nullptr
(或(void *)0
)值的指针变量是未定义的行为,是否意味着这些语言需要地址中的特殊值空间已经死了,这意味着它除了代表的作用外无法使用nullptr
?如果系统在相同的地址处具有真正有用的功能或数据结构,该nullptr
怎么办?这应该永远不会发生,因为编译器编写的每个系统都需要找出一个非冲突的空指针值,这是编译器的编写者责任吗?或者,在"未定义的行为模式"下编程以实现其意图时,需要访问此类函数或数据结构的程序员是否满足?
这看起来模糊了编译器和计算机系统角色的界限.我会问这样做是否正确,但我想这里没有空间.
这取决于"地址空间"这个短语的含义.C标准使用非正式短语,但没有定义它的含义.
对于每个指针类型,必须有一个值(空指针),它将不等于指向任何对象或函数的指针.这意味着,例如,如果指针类型是32位宽,那么该类型的有效非空值最多可以是2 32 -1.如果某些地址具有多个表示,或者如果不是所有表示都对应于有效地址,则可能少于此.
因此,如果您定义"地址空间"以覆盖2 N个不同的地址,其中N是指针的位宽,则是,其中一个值必须保留为空指针值.
另一方面,如果"地址空间"比那个窄(例如,典型的64位系统实际上不能访问2 64个不同的存储器位置),那么保留为空指针的值可以很容易地在"地址空间".
有些事情需要注意:
在大多数现代实现中,所有指针类型都是相同的大小,并且所有指针都表示空指针作为全位零,但是有正当理由,例如,使函数指针比对象指针void*
更宽,或者使得更宽int*
,或者对于空指针,使用除了all-bits-zero之外的表示.
这个答案基于C标准.其中大部分也适用于C++.(一个区别是C++具有指向成员的指针类型,通常比普通指针更宽.)