当前位置: 首页 > 知识库问答 >
问题:

是通过未初始化的指针UB访问静态类成员吗?

逑兴安
2023-03-14

这个问题的后续问题

我们有以下代码:

#include <iostream>

struct A 
{
    static int n;
};

int A::n = 5;

int main() 
{
    A* a; //uninitialized on purpose
    std::cout << a->n; //UB?
}

这种访问是一种未定义的行为吗?一方面,不需要对象来访问静态类成员,另一方面,运算符

注意:GCC和MSVC在没有任何警告的情况下编译此代码,Clang抱怨未初始化的使用。https://godbolt.org/z/Gy5fR2


共有1个答案

许学真
2023-03-14
匿名用户

< code >的语义

...计算点或箭头之前的后缀表达式...表达<代码> E1-

还有一个脚注说:

如果对类成员访问表达式求值,即使结果不需要确定整个后缀表达式的值,也会进行子表达式求值(例如,如果id表达式表示静态成员)。

在这种情况下,计算表达式*a。由于a是一个未初始化的自动变量,因此[dcl.init]/12适用:

如果评估产生不确定的值,则行为未定义,除非在以下情况下:[…]

评估< code>*a显然需要访问指针变量< code>a的值,这是一个不确定的值,因此它是UB。

 类似资料:
  • 考虑以下代码: GCC v6.1编译它,叮当声3.8拒绝它,错误如下: 2:错误:没有成员名为'foo'在'U' struct S{静态constexpr int bar=T::foo;}; 哪个编译器是对的? 会不会是因为在我们尝试在中使用它时不是一个完整的类型? 在这种情况下,它应该被认为是GCC的错误,但我想知道我是否正确之前在错误跟踪器上搜索/打开问题… 编辑 与此同时,我已经向GCC打开

  • 下面是一个示例: 我一直认为它定义得很好(否则的意义是什么),但我不确定。 最近我被告知它实际上是UB,所以我想一劳永逸地弄清楚它。 上面的例子到底有没有引起UB?如果你把类修改成非标准布局,会影响结果吗? 如果是UB,是否有任何解决方法(例如,应用< code>std::launder)? 这整个主题似乎没有实际意义,而且没有得到充分的阐述。 以下是我能够找到的一些信息: > 添加到“char*

  • 本文向大家介绍C ++静态成员变量及其初始化,包括了C ++静态成员变量及其初始化的使用技巧和注意事项,需要的朋友参考一下 静态C ++成员变量是使用static关键字定义的。类中的静态成员变量由所有类对象共享,因为在内存中只有它们的一个副本,而与该类的对象数量无关。 如果没有以任何其他方式初始化静态类成员变量,则在创建类的第一个对象时将其初始化为零。 给出了一个演示静态成员变量及其在C ++中的

  • 问题内容: 我最近刚与Python中的一个错误作斗争。那是那些愚蠢的新手错误之一,但是它让我思考了Python的机制(我是C ++的老程序员,是Python的新手)。我将列出错误的代码并解释如何解决该问题,然后我有两个问题。 场景:我有一个叫做A的类,它有一个字典数据成员,下面是其代码(当然这是简化的): 使用此代码的类为B类: 请注意,每次调用都会初始化类A的新“干净”实例,并在添加前后打印字典

  • 问题内容: 通常,在面向对象的范例中,静态方法只能访问静态变量和静态方法。如果是这样,那么就会出现一个明显的问题,即Java中的main()方法如何才能访问非静态成员(变量或方法),即使它特别是公共静态void … !!! 问题答案: main方法也无权访问非静态成员。

  • 在这两个示例中,通过偏移其他成员的指针来访问结构成员是否会导致未定义/未指定/实现定义的行为? C11§6.7.2.1第14段似乎表明,这应该是实施定义: 结构或联合对象的每个非位字段成员都以适合其类型的实现定义方式对齐。 后来又说: 结构对象中可能有未命名的填充,但在其开头没有。 但是,如下所示的代码似乎相当常见: 该标准似乎保证 与 和< code >( 原始应用程序正在考虑从一个结构字段到另