后续问题 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-> 在未初始化的指针上,这是自找麻烦。
operator->
注意:GCC和MSVC编译此代码时没有任何警告,Clang抱怨未初始化的用法。 https://godbolt.org/z/Gy5fR2
语义 a->n 是吗 *a 会被计算,但不会被访问,因为数据成员是静态的。参见C++17[expr.ref]:
a->n
*a
... 计算点或箭头之前的后缀表达式。。。表情 E1->E2 转换为等效形式 (*(E1)).E2 ...
E1->E2
(*(E1)).E2
还有一个脚注说:
如果对类成员访问表达式求值,则即使不需要结果来确定整个后缀表达式的值(例如,如果id表达式表示静态成员),也会进行子表达式求值。
在本例中,表达式 *a 进行了评估。自从 a 是一个尚未初始化的自动变量,[dcl.init]/12适用于:
a
如果评估产生了不确定的值,则行为是未定义的,但以下情况除外:[……]
评价 *a 显然需要访问指针变量的值 A. ,这是一个不确定的值,因此为UB。
A.