C++ 取消引用无效指针,然后获取结果的地址

C++ 取消引用无效指针,然后获取结果的地址,c++,pointers,C++,Pointers,考虑: int* ptr = (int*)0xDEADBEEF; cout << (void*)&*ptr; int*ptr=(int*)0xDEADBEEF; cout根据规范,取消引用无效指针本身的效果会产生未定义的行为。取消引用后,您做什么都不重要。这是合法的。为什么不呢?您只需将一个值设置为指针,然后访问它。然而,手动赋值显然必须指定为未定义的行为,但这是一般规范所能说的最多的行为。然后,在一些嵌入式软件控制器中使用它,它将为某些设备提供正确的内存映射值…假设变量“

考虑:

int* ptr = (int*)0xDEADBEEF;
cout << (void*)&*ptr;
int*ptr=(int*)0xDEADBEEF;

cout根据规范,取消引用无效指针本身的效果会产生未定义的行为。取消引用后,您做什么都不重要。

这是合法的。为什么不呢?您只需将一个值设置为指针,然后访问它。然而,手动赋值显然必须指定为未定义的行为,但这是一般规范所能说的最多的行为。然后,在一些嵌入式软件控制器中使用它,它将为某些设备提供正确的内存映射值…

假设变量“ptr”不包含指向有效对象的指针,如果程序需要表达式“*ptr”的左值到右值转换,则会发生未定义的行为,如[conv.lval]中指定的那样(ISO/IEC 14882:2011,第82页,4.1[#1])

根据[expr.unary.op](ISO/IEC 14882:2011,第109页,5.3.1[#3]),在计算“&*ptr”期间,程序不需要对子表达式“*ptr”进行左值到右值的转换


因此,它是合法的。

一个好的编译器应该将
&*ptr
的效果转换为
ptr
;所以基本上没问题。但从理论上讲,这可能是一种未定义的行为。我敢肯定,我们以前也有过这种争论,即使是那些对DRs和类似主题做出贡献的人,对现行标准的含义似乎也有一些不同的看法。委员会拒绝引入任何形式的不存在的左值来明确允许这种把戏(如此保守:这是不允许的,因为左值表达式引用一个对象,或者一些这样的措辞,而
*ptr
不是一个对象),但不存在的引用上不会发生左值到右值的转换我记得Stephan T Lavavej在第9频道的一个标准图书馆教程视频中评论说,对
n
元素数组说
&myArray[n]
是非法的,你应该改为做
&myArray[0]+n
。换句话说,指针超出数组的末尾是可以的,但是一旦指针超出数组的边界,就取消对它的引用是非法的。@Praetorian(和Kerrek):甚至在“超过末尾的一个”之外形成指针值都是未定义的行为对于基本原理,考虑一个假设的实现,其中增加地址导致指针类型的陷阱表示,或者溢出导致硬件异常。地址不是C++标准中的数字,即使它们在所有已知的实现中:对于标准未分配的地址空间是一个打哈欠的VoI。作为参考,在C(至少C99)中,标准规定
&*E
等同于
E
;这是明确允许的。因此剩下的唯一问题(在C中)在第一个地方是否创建一个无效指针是不明确的。我从来没有在C++标准中找到等价语言。这不是因为一个子表达式是在引用无效的指针。但是正如Oli Charlesworth所指出的,<代码>和*PTR < /代码>相当于代码> PTR < /Cord>,所以不可废止。不。事实上Oli Charlesworth。注释,和*PTR不等同于C++中的代码> PTR< /Cord>。C99是完全不同的语言。如果你费心读到他的评论到最后,你会看到他用“我从来没有在C++标准中找到等价语言”来结束它。谢谢。注意,在C(至少C99)中这个标准说,<代码>和*e <代码>相当于代码> E<代码>;这是明确允许的。(但我从未在C++标准中找到等价的)。“即使是空指针”但不是“即使是结束指针”)它认为,在规范部分中所阐述的逻辑含义是:<代码>和*>代码>对于空指针也是一个“否”。有趣的是,无论是谁写的脚注,都会从C++标准中得出相同的含义,即<代码> >代码>是没有操作符重载的“无”。“史提夫:是的,它是FuiCu。看看这个脚注是如何被主体所暗示的。如果它是可信的,如果C++后来由于不相容的原因而做出了明确的行为,那就奇怪了。”OLI:是的,我认为整个事情都是一团糟。我的回答是,即使它是合法的,我也不想与之相关。所以我不会写它。如果我写过C或C++实现,我会确保它工作,并且可能会对它进行惊人的高级别警告。C++中明确地指出,你不能从空指针中形成引用。我认为合理地假设你也不可能通过取消引用来形成一个左值。在C99中,C++不需要兼容,因为C++ 98不是C99的“后续”。@ StestJeops:实际上,C使<代码>和*>代码>一个特殊的情况(在描述代码<和代码>的段落)。C++没有区分这个区别,但是,我不能在标准中明确地找到任何空指针的引用。(没有以下左值到右值的转换)是未定义的行为(尽管在几个注释中提到)。您的第二段有引用吗?是的,5.3.1一元运算符[#3]“一元运算符和运算符的结果是指向其操作数的指针。操作数应为左值或限定值。“这可能会成功!编辑到您的答案中,然后我将验证并可能接受。(顺便说一句,请使用
@
通知语法;我偶然发现您的评论回复。)@TomalakGeret'kal,在这里,我添加了另一个对标准的引用,并稍微澄清了措辞,第一行应该是“poi”