C++;标准:取消引用空指针以获取引用? 我想知道C++标准对这样的代码的说明: int* ptr = NULL; int& ref = *ptr; int* ptr2 = &ref;
实际上,结果是C++;标准:取消引用空指针以获取引用? 我想知道C++标准对这样的代码的说明: int* ptr = NULL; int& ref = *ptr; int* ptr2 = &ref;,c++,pointers,reference,null,C++,Pointers,Reference,Null,实际上,结果是ptr2为空,但我想知道,这只是一个实现细节,还是在标准中定义得很好? 在不同的情况下,对NULL指针的解引用应该会导致崩溃,但在这里,我解引用它是为了得到一个引用,该引用由编译器作为指针实现,因此实际上没有对NULL的实际解引用 取消引用空指针是未定义的行为。在取消引用某个值之前,应检查该值是否为空。取消引用空指针是未定义的行为 事实上,本标准在注释(8.3.2/4“参考”)中指出了这一确切情况: 注意:特别是,在定义良好的程序中不能存在空引用,因为 创建这样一个引用的方法是将它
ptr2
为空,但我想知道,这只是一个实现细节,还是在标准中定义得很好?在不同的情况下,对NULL指针的解引用应该会导致崩溃,但在这里,我解引用它是为了得到一个引用,该引用由编译器作为指针实现,因此实际上没有对NULL的实际解引用 取消引用空指针是未定义的行为。在取消引用某个值之前,应检查该值是否为空。取消引用空指针是未定义的行为 事实上,本标准在注释(8.3.2/4“参考”)中指出了这一确切情况: 注意:特别是,在定义良好的程序中不能存在空引用,因为 创建这样一个引用的方法是将它绑定到通过取消引用空指针而获得的“对象”,这会导致未定义的行为
顺便说一句:有一次我意识到空指针可以以定义良好的方式“去引用”,那就是作为
sizeof
操作符的操作数,因为sizeof
的操作数实际上没有被计算(所以去引用永远不会发生)< P> >空指针是C++标准中显式未定义的行为,所以您看到的是实现特定的。
从C++0x标准草案中的1.9.4中复制(在这方面与以前的标准类似):
还描述了某些其他操作
在本国际标准中:
未定义(例如
取消对空指针的引用)。
[注:本国际标准
不要求
包含
未定义的行为。-结束注释]
为了完整起见,本文:专门讨论了这个问题
int& ref = *ptr;
上面的语句实际上并没有取消引用任何内容。因此,除非您使用
ref
(无效)。为这个问题提供了一个很好的答案。链接重复:实际上,如果它是typeid
的操作数,如果它是PolymorphClass*
类型的空指针,那么它将被解引用和求值。它仍然是定义良好的(抛出bad\u typeid
)。我真的不喜欢那种特殊的typeid
处理。不允许空引用是很不幸的。它展示了一些很酷的特性,但我想它只是使代码复杂化了(如果前提条件可用并且代码可以更好地验证,则可以安全地使用空引用是变量类型上的运算符,而不是值。空指针确实有类型。@jforberg:我没有看到有人在这里提出相反的说法?@Lightness没有人。我只是澄清一下。这很有趣,因为没有人能够显示在标准中明确取消引用空指针的位置。这里的标准不正确。@curiousguy:8.3.2.5再次提到,取消引用空指针是未定义的。但你是对的,它这样做就像在其他地方解释过一样。无论如何,1.3.13解释说,任何未明确定义的行为都被认为是未定义的,因此可能是这种情况。“8.3.2.5”顺便说一句,拼写为8.3.2/5。没有8.3.2.5节。“任何未明确定义的行为都被视为未定义"你是对的:只有当指针指向某个对象时,才定义取消引用指针。但是如果标准对此有明确规定,则会更清楚一点,并且在这一非问题上花费的电子墨水会更少。注释是非规范性的。事实上,此注释被删除是因为声明的理由是它不是un取消引用空指针的定义行为。无意义。一元*
实际上是取消引用运算符。它实际上执行取消引用操作。@curiousguy:我建议您编译它,并在反汇编程序中查看代码。引用ref
本质上是一个指针,因此上面的语句只是一个指针赋值你误解了我的意思。我不在乎生成了什么汇编代码。根据你的说法,什么是*ptr
?@curiousguy:*ptr
确实是一种去引用。但这并不意味着它实际上已经完成了(评估)。例如,你可以编写sizeof(*ptr)
和表达式*ptr
保证在运行时不会求值。实际上,sizeof
的操作数不会求值:您可以写入sizeof(1./0)
没有任何问题。这是因为sizeof
只关心其操作数的类型。&
的操作数会被计算,否则的话地址会应用于什么?嗯……非常有创意的想法。所以,用nullthis
调用成员函数是允许的!!!我想知道他们在冒烟什么。总之,7年后,没有任何事情朝着这种疯狂的方向发展。事实上,根据(由于左值到右值的转换)的说法,事实并非如此很有趣,当232的C++实现隐式地包含IEEE-75,它定义了除以正和负的零的整数时,使用了以零除法的例子。整数除以0是UB,但是这个例子没有指定。你必须使用“多”这个词是UB的一个例子。