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
    是一个废弃的值表达式
  • :未发生左值到右值的转换
  • :aka严格别名规则,仅当左值转换为右值时
  • 所以我的结论是,没有任何东西明确地说这是未定义的行为。但我清楚地记得,一些平台在间接寻址上捕获无效指针。我的推理出了什么问题?

    说:

    指针类型的每个值都是以下值之一:

    • 指向对象或函数的指针(该指针被称为指向对象或函数),或
    • 超过对象结尾([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转换”。