【问题标题】:Is accessing static class member via unitilialized pointer UB?是否通过未初始化的指针 UB 访问静态类成员?
【发布时间】:2020-03-13 07:07:54
【问题描述】:

this one的后续问题

我们有以下代码:

#include <iostream>

struct A 
{
    static int n;
};

int A::n = 5;

int main() 
{
    A* a; //uninitialized on purpose
    std::cout << a->n; //UB?
}

这种访问是一种未定义的行为吗?一方面,访问静态类成员不需要对象,另一方面,未初始化指针上的operator-&gt; 在自找麻烦。

注意:GCC 和 MSVC 编译此代码时没有任何警告,Clang 抱怨未初始化的使用。 https://godbolt.org/z/Gy5fR2

【问题讨论】:

  • 类似问题here 虽然我对最佳答案持怀疑态度
  • 我重新打开了这个,因为副本处理空指针,而这个问题处理未初始化的指针。由于不清楚将*应用于空指针是否是UB,所以问题不同。
  • @MM 这很有趣,因为最初链接为重复的问题 (stackoverflow.com/questions/3498444/…) 的最佳答案是“是的,它是 UB”,并且与您链接的问题一样关闭,这说“不,不是”。
  • @Yksisarvinen 好吧,我已经走了出去,并发布了另一个问题的答案
  • @curiousguy 我同意你的看法。我不清楚为什么委员会不能分配更多时间来解决这些问题(毕竟,它现在的成员比以往任何时候都多)。至少,我认为在引入更多问题的内存/对象模型进一步“改进”之前应该解决这类问题。

标签: c++ static language-lawyer undefined-behavior


【解决方案1】:

a-&gt;n 的语义是 *a 被评估,但不被访问,因为数据成员是静态的。参见 C++17 [expr.ref]:

...计算点或箭头之前的后缀表达式...表达式 E1-&gt;E2 转换为等价形式 (*(E1)).E2 ...

还有一个脚注说:

如果类成员访问表达式被求值,子表达式求值即使结果对于确定整个后缀表达式的值是不必要的,例如如果 id-expression 表示静态成员。

在这种情况下,表达式 *a 被计算。由于a是一个没有被初始化的自动变量,所以[dcl.init]/12适用:

如果评估产生不确定的值,则行为未定义,但以下情况除外:[ ... ]

评估*a显然需要访问指针变量a的值,这是一个不确定的值,因此它是UB。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2010-10-16
  • 1970-01-01
  • 1970-01-01
  • 2011-07-18
  • 2012-02-13
  • 2020-08-05
  • 1970-01-01
  • 2015-05-18
相关资源
最近更新 更多