编辑:这与C++ Standard Core Language Active Issues
上的有效问题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
是否为f_ref
?
第二个问题:如果C ++最终通过空指针定义间接行为,这是否意味着NULL
必须检查const b *f_const_ref(const c &reference_to_c) { return &reference_to_c; }
? (我想答案取决于标准允许的内容,即,如果它说“为多重继承而未定义对基类的NULL引用”,那么答案显然是否定的。)
对于最后一个难题,现在考虑一下:
f_const_ref
&reference_to_c
必须检查NULL
到f
吗?顺便说一下,使用VC ++ 2010,所有三个函数都优化为NULL
,也就是说,所有三个函数都针对{{1}}测试输入。
因此,鉴于您无法在定义良好的程序中传递空引用,这是否意味着如果C ++标准最终允许间接通过空指针,则它不会导致表达式或子表达式,否则将绑定到空指针并创建一个空引用?换句话说,如果标准允许通过空指针进行间接寻址,那么它们允许的各种方式是什么?
答案 0 :(得分:6)
取消引用NULL指针无效(即未定义的行为)。
因此永远不可能从NULL(在有效代码中)获取引用。
因此,您获得的任何引用都将永远不会为NULL,因此您无需检查它。
第一个问题:f_ref是否需要检查& reference_to_c是否为NULL?
没有
第二个问题:如果C ++最终通过空指针定义间接行为,这是否意味着f_ref必须检查NULL?
确实如此。它未定义的行为。因此,任何进一步的推测都毫无价值。
对于最后一个难题,f_const_ref是否必须检查& reference_to_c为NULL?
没有
答案 1 :(得分:3)
如果f_ref
或f_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;
}
答案 2 :(得分:2)
C ++ 不允许这样做。对NULL
的引用是非法的,标准方面将导致未定义的行为。
话虽如此,我从未见过编译器做任何事情而不是你的期望。
答案 3 :(得分:1)
&reference_to_c
永远不能为NULL。在函数参数中,必须使用某个有效对象初始化引用。所以&reference_to_c
不能为NULL。