3

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

这是 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吗?
  • 如果ptr指向除 之外的其他东西,是否会违反混叠int

请注意,我专门询问如何形成参考,而不是使用它来读取值。

编辑 09/12/2019:接受以下答案:

  • 是否int const volatile& ref = *ptr;读取指向对象的值?
    • 不。
  • 这是未定义的时间ptr == nullptr吗?
    • 是的,*ptr在空指针上是未定义的。
  • ptr如果指向不同类型的对象, 形成引用是否违反了别名?
    • 不,只是形成引用并不违反严格的别名。
    • 大概reinterpret_cast-ing 对正确类型的引用是允许且有效的。
4

1 回答 1

4

[basic.compound]/3 ...指针类型的每个值都是以下之一:

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

(3.2) — 超过对象末尾的指针 (8.7),或

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

(3.4) — 无效的指针值。


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

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

于 2019-12-06T01:44:17.180 回答