标准如何允许通过空指针进行间接寻址

How would the standard allow indirection through a null pointer?

本文关键字:间接寻址 空指针 何允许 标准      更新时间:2023-10-16

EDIT:这与C++标准核心语言活动问题上的活动问题232有关

因此,真正的问题是,标准如何允许通过空指针进行间接寻址?

考虑以下代码:

struct a { int x; };
struct b { int y; };
struct c: a, b { };
b *f(c *pointer_to_c) { return pointer_to_c; }

f(...)必须测试pointer_to_c是否是NULL,如果是则返回NULL。(无论如何投射,NULL指针始终是NULL指针。(

现在,考虑以下内容:

b *f_ref(c &reference_to_c) { return &reference_to_c; }

第一个问题:f_ref是否需要检查&reference_to_c是否为NULL?第二个问题:如果C++最终通过空指针定义了间接行为,这是否意味着f_ref必须检查NULL?(我想答案取决于标准允许的内容,即,如果它说"对基类的NULL引用对于多重继承是未定义的",那么答案显然是否定的。(

对于最后一个谜题,现在考虑一下:

const b *f_const_ref(const c &reference_to_c) { return &reference_to_c; }

f_const_ref是否必须检查&reference_to_cNULL?顺便说一句,在VC++2010中,所有三个函数都被优化到了f,也就是说,所有三种函数都针对NULL测试输入。

因此,假设你不能在定义良好的程序中传递null引用,这是否意味着如果C++标准最终允许通过null指针进行间接操作,它就不能产生一个绑定到null指针并创建null引用的表达式或子表达式?换言之,如果标准允许通过空指针进行间接寻址,那么它们允许间接寻址的各种方式是什么?

取消引用NULL指针无效(即未定义的行为(。

因此,从NULL(在有效代码中(中获取引用是不可能的。

因此,你得到的任何引用都不会是NULL,因此你不需要检查它

第一个问题:f_ref是否需要检查&reference_to_c为空?

没有。

第二个问题:如果C++最终通过空指针定义了间接行为,这是否意味着f_ref必须检查null?

确实如此。其未定义的行为。因此,任何进一步的猜测都毫无价值。

对于最后一个谜题,f_const_ref必须检查&reference_to_c为NULL?

没有。

如果您在f_reff_const_ref中的引用为NULL,则表示您已深入到未定义行为的领域。

这是未定义的,因为获取NULL引用的唯一方法是取消引用NULL指针。因此,下面的内容是未定义的,尽管在g++4.5.2上它将输出0。

#include <iostream>
struct C {};
C* foo(C& r) {  return &r; }
int main() {
  C* c = NULL;
  std::cout << foo(*c) << std::endl;
  return 0;
}

C++不允许这样做。对NULL的引用是非法的,在标准方面会导致未定义的行为。

话虽如此,我从未见过编译器做任何超出您预期的事情。

&reference_to_c永远不能为NULL。在函数参数中,引用必须使用一些有效对象进行初始化。因此&reference_to_c不能为NULL。