首页 >后端开发 >C++ >为什么在 C 中允许使用空指针访问静态成员?

为什么在 C 中允许使用空指针访问静态成员?

Susan Sarandon
Susan Sarandon原创
2024-11-03 01:33:02936浏览

Why is it allowed to access static members using a null pointer in C  ?

在 C 中使用空指针访问静态成员

上下文

考虑以下程序:

<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 的情况。这种行为是明确定义的。

静态成员的行为与通过空指针访问非静态成员不同,后者确实应该触发未定义的行为,因为它意味着无效的对象标识。相反,访问静态成员不需要对象标识,并且它们的行为在标准中明确定义。

其他注意事项

  • CWG 问题 #232 强调了处理之间的差异在 C 标准中通过空指针间接调用,表明它本身可能不会导致未定义的行为。
  • CWG 问题 #315 专门解决了通过空指针调用成员函数的场景,重申间接本身是除非涉及依赖于对象标识的进一步操作,否则不是错误。
  • 丢弃表达式结果(丢弃值表达式)的处理方式与访问值不同,这可能会根据上下文触发错误。

结论

给定的程序不会造成任何危害,因为在访问静态成员的上下文中允许对 *d 进行求值。仅通过空指针间接不一定会导致未定义的行为,但重要的是要意识到与需要对象标识的进一步操作相关的潜在风险。

以上是为什么在 C 中允许使用空指针访问静态成员?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn