C++ 取消对空指针的引用

C++ 取消对空指针的引用,c++,c,null,pointers,C++,C,Null,Pointers,这是否是未定义的行为?我浏览了一些相关的问题,但是这个特定的方面没有显示出来。是的,这将是未定义的行为,但是您的编译器可能会优化&* 为什么它是未定义的,是因为您试图访问可寻址空间之外的内存。是的,取消引用空指针是未定义的行为。指针上下文中的整数常量0是空指针。就这样 现在,如果你的第二行是int*q=p这将是一个简单的指针赋值。如果编译器删除&*并减少对赋值的解引用,那么您就可以了。IMHO,就这两个代码行而言,地址空间之外没有任何访问权限。第二条语句只是获取地址(*p),该地址将再次为“p”

这是否是未定义的行为?我浏览了一些相关的问题,但是这个特定的方面没有显示出来。

是的,这将是未定义的行为,但是您的编译器可能会优化
&*


为什么它是未定义的,是因为您试图访问可寻址空间之外的内存。

是的,取消引用空指针是未定义的行为。指针上下文中的整数常量0是空指针。就这样


现在,如果你的第二行是
int*q=p这将是一个简单的指针赋值。如果编译器删除
&*
并减少对赋值的解引用,那么您就可以了。

IMHO,就这两个代码行而言,地址空间之外没有任何访问权限。第二条语句只是获取地址(*p),该地址将再次为“p”,因此它将存储“0”。但是这个位置永远不会被访问。

这个问题的答案是:它取决于您遵循的语言标准:-)

在C90和C++中,这是无效的,因为您对空指针执行间接操作(通过执行代码> *P<代码>),这样做会导致未定义的行为。 但是,在C99中,这是有效的、格式良好的和定义良好的。在C99中,如果一元数
和的操作数是通过应用一元数*或执行下标(
[]
)获得的,则既不应用
&
也不应用
*
[]
。例如:

int* p = 0;
int* q = &*p;
同样地

int* p = 0;
int* q = &*p; // In C99, this is equivalent to int* q = p;
根据C99§6.5.3.2/3:

如果[一元
&
运算符的]操作数是一元
*
运算符的结果,则不会对该运算符和
&
运算符进行求值,结果就像两者都被省略一样,但运算符上的约束仍然适用,且结果不是左值

类似地,如果操作数是
[]
运算符的结果,则不会计算
&
运算符和
[]
运算符所隐含的一元
*
,结果就好像删除了
&
运算符,而将
[]
运算符更改为
+
运算符一样

(及其脚注#84):

因此,
&*E
相当于
E
(即使
E
是空指针)


它在所有情况下都是未定义的。若编译器对它进行优化,那个么它就是某种行为。未定义的行为意味着任何事情都可能发生,包括飞行的大象和什么都没有。未定义的行为意味着根据规范,行为没有定义。当然,这并不排除构造在其他级别上仍有一些定义良好的行为。duplicate:@Naveen我的程序中没有引用…?@FredOverflow:据我所知,两者都在做相同的事情,取消对调用未定义行为的空指针的引用。此问题的可能重复实际上不是这些问题的重复。“此代码似乎实现了C++中空引用的返回”问题询问了C++特定的语义(而此问题询问的是C和C++),实际上并没有询问取消引用空指针是否会导致未定义的行为。“去引用空指针”这个问题,尽管它的标题是,实际上是问“什么是空指针?”而不是“去引用它是未定义的吗?”但它仍然是未定义的。仅仅因为具有特定优化级别的特定编译器的特定版本可以处理此问题,并不意味着“您没事”-因为它未定义,如果优化级别更改(或在以“R”结尾的几个月内),它可能会在编译器的下一个版本中停止工作。+1。我将在一个注释中匆忙地添加到另一个答案,直到我看到这个答案:“我也会注意到,在空指针上执行间接操作可能不是C++中的意图导致了未定义的行为(PER)。然而,对于该缺陷的建议的决议没有纳入到C++ 0x最终委员会草案中,所以它不太可能在下一个C++标准发布之前被修复。我相信在C++中这也是有效的。由于一元*运算符创建引用(对象的别名),因此不会发生反引用。然后,应用于引用的&运算符再次返回空指针。见第5.3.1节-1@Martin我们已经在去年某个时候的另一个答案中证明了你对“撤销引用”的理解是错误的。将一元
*
应用于指针解引用,无论是否完成左值到右值的转换都是无关的。编辑:请参阅此答案的评论线程:特别注意
3.8/5
的措辞,其中说“这样的指针可以被取消引用,但产生的左值只能以有限的方式使用,如下所述。”以及各种注释,它们清楚地表明“取消引用”适用于将地址转换为左值。另一个操作,将左值转换为右值,不称为取消引用,但称为左值到右值转换或简单地“访问存储值”(如3.10/15)等。
int* p = 0;
int* q = &p[0]; // In C99, this is equivalent to int* q = p + 0;