在 C 中,可以通过空指针访问类的静态成员,而不会调用未定义的行为。这种行为可能看起来令人惊讶,但可以通过检查语言的定义和基本原理来解释。
通过空指针访问类成员时,该行为很好 -只要操作数的计算不需要指示对象的身份或存储值即可定义。例如,访问静态成员变量 d->a 只是计算表达式 *(d) 以获得对象的引用,但不执行需要初始化引用对象的操作。
此计算该过程由 [expr.ref]/2 支持,其中指出 d->a 转换为 ((d)).a。由 *d 表示的 ((d)) 的计算继续进行,不会触发任何错误,因为不需要 d 引用的对象。
C 标准没有明确声明通过空指针的间接寻址本质上会导致未定义的行为。事实上,CWG 问题 #232 和 #315 表明,单纯的间接寻址并没有问题。
这一立场的主要论据在于存在明确定义的场景,其中允许通过空指针进行间接寻址。例如,[expr.typeid]/2 允许 typeid(*((A*)0)) 抛出 bad_typeid 异常,即使 *d 计算结果为 null。如果只是间接调用 UB,则该语句不会被明确定义。
在您的示例中,
<code class="cpp">int main() { demo* d = nullptr; d->fun(); std::cout << d->a; return 0; }</code>
程序编译并运行时没有错误是因为调用静态成员函数或访问静态变量不需要指示对象的标识。因此,您的程序不存在任何固有问题或未定义的行为。
以上是您可以在没有未定义行为的情况下使用空指针访问 C 中的静态成员吗?的详细内容。更多信息请关注PHP中文网其他相关文章!