You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编译器将表达式a->i替换为常量1是否合法?是否因a未被odr-used?

解答:nullptr访问静态成员时a未被odr-used的说法是否正确?

首先看这段可跨GCC、clang和VS2017正常编译的代码:

struct A { static const int i = 1; };
int f() {
    A *a = nullptr;
    return a->i;
}

你的问题是:认为这段代码合法的原因是a在表达式a->i中未被odr-used,这个说法是否正确?

答案是:完全正确。

我们可以结合C++标准的规则来拆解原因:

根据标准中关于odr-used的定义([basic.def.odr]/4):

A variable x whose name appears as a potentially-evaluated expression ex is odr-used by ex unless applying the lvalue-to-rvalue conversion (7.1) to x yields a constant expression (8.6) that does not invoke any non-trivial functions and, if x is an object, ex is an element of the set of potential results of an expression e, where either the lvalue-to-rvalue conversion (7.1) is applied to e, or e is a discarded-value expression (8.2).

具体到这个场景:

  • 表达式a->i本质等价于A::i——因为i是类的静态成员,编译器只需要通过a的类型(A*)来定位要访问的静态成员,并不会真的去解引用a这个空指针。
  • 按照[basic.def.odr]/2 (2.3)的规则,a属于表达式a->i的潜在结果集元素,而对a->i应用左值到右值转换后,得到的是常量1,完全满足上述规则中的“除非”例外条件。

这就意味着a并没有被odr-used,所以即使它是nullptr,代码依然合法,编译器可以直接将a->i替换为常量值1。

内容的提问来源于stack exchange,提问作者Ayrosa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:04:45