通过统一指针UB访问静态类成员吗?

Yks*_*nen 2 c++ static undefined-behavior language-lawyer

问题的后续问题

我们有以下代码:

#include <iostream>

struct A 
{
    static int n;
};

int A::n = 5;

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

这样的访问是否为未定义行为?一方面,不需要对象来访问静态类成员,另一方面,operator->在未初始化的指针正在请求麻烦的情况下。

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

Bri*_*ian 10

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

...计算点或箭头之前的后缀表达式...该表达式 E1->E2将转换为等效形式(*(E1)).E2...

还有一个脚注说:

如果评估了类成员访问表达式,则即使不需要确定整个后缀表达式的值(例如,如果id-expression表示静态成员),也将进行子表达式评估。

在这种情况下,将对表达式*a求值。由于a是尚未初始化的自动变量,因此适用[dcl.init] / 12:

如果通过评估产生不确定的值,则该行为是不确定的,除了以下情况:[...]

*a清楚地进行评估需要访问指针变量的值,该值a是不确定的值,因此为UB。