C++ 形成对对象的引用是否构成访问?

C++ 形成对对象的引用是否构成访问?,c++,language-lawyer,undefined-behavior,null-pointer,reference-binding,C++,Language Lawyer,Undefined Behavior,Null Pointer,Reference Binding,形成对对象的引用是否构成访问 以下是GCC和Clang目前的工作: void test(int const volatile* ptr) noexcept { *ptr; // movl (%rdi), eax // Reads *ptr [[maybe_unused]] int const volatile& ref = *ptr; // Does not read *ptr } 我的问题是关于声明的 [[maybe_unused]] int const volat

形成对对象的引用是否构成访问

以下是GCC和Clang目前的工作:

void test(int const volatile* ptr) noexcept {
  *ptr;  // movl (%rdi), eax  // Reads *ptr
  [[maybe_unused]] int const volatile& ref = *ptr;  // Does not read *ptr
}
我的问题是关于声明的

  [[maybe_unused]] int const volatile& ref = *ptr;
  • 根据抽象机器,它是否读取由
    ptr
    指向的对象的值
  • 如果
    ptr==nullptr
    ,那么该语句单独是否是未定义的行为?
    • 是,空指针上的间接寻址为UB-
  • 如果
    ptr
    指向的不是
    int
    ,是否会违反别名
请注意,我特别询问如何形成引用,而不是如何使用它来读取值

编辑2019年12月9日:接受以下答案:

  • int const volatile&ref=*ptr读取指向对象的值?
    
    • 没有
  • ptr==nullptr
    时,这是否未定义?
    • 是,空指针上的
      *ptr
      未定义
  • 如果
    ptr
    指向不同类型的对象,则形成引用是否存在别名冲突?
    • 不,只是形成引用并不违反严格的别名
    • 大概
      重新解释\u cast
      -允许并有效地引用正确的类型
[碱性化合物]/3。。。指针类型的每个值都是以下值之一:

(3.1)-指向对象或函数的指针(该指针被称为指向对象或函数),或

(3.2)-超过对象末端的指针(8.7),或

(3.3)-该类型的空指针值(7.11),或

(3.4)-无效的指针值


[expr.unary.op]/1一元
*
运算符执行间接寻址:应用该运算符的表达式应为指向对象类型的指针,或指向函数类型的指针,结果为引用表达式所指向的对象或函数的左值


因此,表达式
*ptr
的含义仅定义为指向对象或函数的指针
ptr
,即,其值属于[basic.component]/(3.1)的指针。在所有其他情况下,该表达式表现出未定义的行为。

对于第二个问题,它是UB,请原谅我问,语言规范在哪里说
*ptr本身会导致解引用和相应的内存访问吗?那不是很好吗?或者它是明确允许的,而不是NOOP'd,因为它可能会取消对硬件IO地址的引用,这在读取时会产生一些副作用?不能引用这样的添加作为注释:引用甚至不需要存在,它只是一个别名。最多只能捕获对象的地址,因此不应进行访问。形成引用不会访问值,也不是严格的别名violation@curiousguyC和C++委员会希望编译器编写者认识到“标准不要求”。这是对他们的邀请,让他们服务于客户的需求,而不是对他们的忽视。我不责怪委员会为乌兰巴托建立的疯狂宗教,但不幸的是,怀疑该宗教的信徒会阻止任何将语言纳入标准的尝试,即除严格遵守程序外,被定性为UB的内容不在委员会的管辖范围内。感谢您找到我的问题所涉及的标准部分。UB是在
*ptr
处出现,还是仅在访问结果左值时出现?我对该标准的理解是,
*ptr
本身表现出未定义的行为,而不管对结果做了什么。“表达式*ptr的含义仅针对指向对象或函数的指针ptr定义”不需要对象存在就可以引用它。