考虑以下程序:
<code class="cpp">#include <iostream> class Demo { public: static void func() { std::cout << "func() called" << std::endl; } static int num = 9; }; int main() { Demo* d = nullptr; d->func(); std::cout << d->num << std::endl; return 0; }</code>
该程序编译并运行没有错误,而通过空指针访问静态成员通常被认为是未定义的行为。为什么允许这样做?
TL;DR:
给定的程序不会触发未定义的行为,因为通过空指针的间接寻址不是本质上是有问题的,除非它涉及依赖于有效对象标识的进一步操作。
解释:
通过空指针的间接是否本质上是未定义的行为一直是一个争论的问题。程序中唯一有问题的操作是表达式 d->a 的计算。由于指针解引用规则,
d->a 等效于 (*d).a。然而,即使 *d 未定义,表达式 *d 仍会被求值,特别是当其结果被丢弃时,如 d->a 的情况。这种行为是明确定义的。
静态成员的行为与通过空指针访问非静态成员不同,后者确实应该触发未定义的行为,因为它意味着无效的对象标识。相反,访问静态成员不需要对象标识,并且它们的行为在标准中明确定义。
给定的程序不会造成任何危害,因为在访问静态成员的上下文中允许对 *d 进行求值。仅通过空指针间接不一定会导致未定义的行为,但重要的是要意识到与需要对象标识的进一步操作相关的潜在风险。
以上是为什么在 C 中允许使用空指针访问静态成员?的详细内容。更多信息请关注PHP中文网其他相关文章!