C++ 如果没有发生左值到右值的转换,取消引用无效指针是否合法
尽我所能,我见过的最接近的答案是,有两个完全相反的答案(!) 问题很简单,这合法吗C++ 如果没有发生左值到右值的转换,取消引用无效指针是否合法,c++,language-lawyer,C++,Language Lawyer,尽我所能,我见过的最接近的答案是,有两个完全相反的答案(!) 问题很简单,这合法吗 auto p = reinterpret_cast<int*>(0xbadface); *p; // legal? auto p=reinterpret\u cast(0xbadface); *p、 //合法的 我对这件事的看法 :对可浇铸的内容没有限制 :仅表示结果为左值 :仅说明无法对对象执行的操作,此处没有对象 :*p是一个废弃的值表达式 :未发生左值到右值的转换 :aka严格别名规则,仅
auto p = reinterpret_cast<int*>(0xbadface);
*p; // legal?
auto p=reinterpret\u cast(0xbadface);
*p、 //合法的
我对这件事的看法
*p
是一个废弃的值表达式- 指向对象或函数的指针(该指针被称为指向对象或函数),或
- 超过对象结尾([expr.add])的指针,或
- 该类型的空指针值([conv.ptr]),或
- 无效的指针值
p
是无效的指针值
说:
通过无效指针值进行间接寻址并传递无效指针
指向解除分配函数的指针值具有未定义的行为。任何
无效指针值的其他用法已定义实现
行为
正如间接寻址运算符被称为通过执行间接寻址,我想说,表达式*p
导致UB,无论结果是否被使用
。。。某些平台在间接寻址上捕获无效指针
大多数平台都存在无效地址访问的陷阱。这与这个问题没有任何矛盾。在*p中发生了什么的问题代码>归结为是否尝试实际获取无效地址
获取的问题非常类似于(通过空指针进行间接寻址)。正如你已经指出的,*p代码>是一个,因此不会发生(“提取”):
汤姆·普拉姆:
…只有“获取”的行为,即从左值到右值的转换,才会触发格式错误或未定义的行为
随后:
2003年10月会议记录:
我们一致认为标准中的方法似乎还可以:p=0*p代码>是
这并非天生的错误。左值到右值的转换将给出
未定义的行为
至于reinterpret_cast(0xbadface)
是否生成有效指针,实际上在具有严格指针安全性的实现中,它不会是安全派生的指针,因此无效,任何使用都是无效的
但是如果生成的指针是有效的(否则就不可能使用从二进制库和用C或其他语言编写的组件返回的指针)。你真的认为这合法吗?@Passer“唯一可能产生副作用的方法是如果它是UB…”你抓住了我的想法:-)相关:来自标准:结果是一个左值,表示表达式指向的对象或函数“。你的指针没有指向任何对象,因此这一行不适用,并且在该段中没有其他定义结果。同样相关的,这显然是答案。这也证明了链接的问题接受了错误的答案。@Passenger值得注意的是,允许实现创建对象,如果它放宽了指针安全性,则通过非安全派生的指针访问有效对象可能是合法的。它允许类似于volatile int*output\u pins=reinterpret\u cast(0x0800)的内容代码>在特定实现中是合法的(如嵌入式编程)。我假设0xbadface
不是指向有效对象的指针。如果0xbadface指向映射到内存空间的硬件整数会怎么样?通过消除过程,我们可以推断p是无效的指针值。100%的人不同意。你是怎么推断出来的?从整数到指针的映射以及从整数到指针的映射大多是由实现定义的,没有任何东西禁止实现在重新解释转换(0xbadface)
的结果中为您提供指向某个现有对象的指针。如果p
确实具有无效的指针值,该怎么办<代码>整数*p=新整数;删除p*p代码>。是UB吗?是的,是UB,达到存储期限的末尾。该实现可以显式地检查并捕获对已删除指针的解引用。但是,这里没有左值到右值的转换。这是另一种情况吗?空指针可以取消引用(无需l-to-r转换),但无效指针不能取消引用?假定随机地址不指向某个对象或指向另一个对象,它显然不是空指针。然后它只能是一个无效指针。[basic.stc]并没有给出无效指针的定义,只是获取无效指针的一种可能方法。谢谢,答案已更新。IMHO标准在[basic.stc]中如何应用该术语方面存在缺陷。我想他们的意思是说“间接的然后是l-to-r转换”。