是否通过单元化指针 UB 访问静态 class 成员?

Is accessing static class member via unitilialized pointer UB?

的后续问题

我们有以下代码:

#include <iostream>

struct A 
{
    static int n;
};

int A::n = 5;

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

这样的访问是未定义的行为吗?一方面,访问静态 class 成员不需要任何对象,另一方面,未初始化指针上的 operator-> 自找麻烦。

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

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

... The postfix expression before the dot or arrow is evaluated ... The expression E1->E2 is converted to the equivalent form (*(E1)).E2 ...

还有一个脚注说:

If the class member access expression is evaluated, the subexpression evaluation happens even if the result is unnecessary to determine the value of the entire postfix expression, for example if the id-expression denotes a static member.

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

If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following cases: [ ... ]

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