【问题标题】:Undefined behaviour of Designated initializers in C++C++ 中指定初始值设定项的未定义行为
【发布时间】:2021-07-21 11:45:52
【问题描述】:

在我尝试过的所有编译中都接受了以下 C++20 程序,而没有任何警告:

struct A { const int & x = z; int y = x; int z; };

int main()
{
    return A{.z=3}.y;
}

https://gcc.godbolt.org/z/nqb95zb7c

但是每个程序都会返回一些任意值。假设这是未定义的行为是否正确?

【问题讨论】:

  • y = x,所以y = z在初始化之前读取z
  • GCC 指出 @Jarod42 评论和没有代码的 clang 保释 - 现场 - godbolt.org/z/3fxKhrKnb
  • 您还可以使用常量评估来捕获未定义的行为:godbolt.org/z/WYv1W8PcW(这使得 gcc 指出未初始化的访问)
  • 假设这是未定义的行为是否正确? 是的,因为读取未初始化的变量是未定义的行为。可能是任意值,可能会崩溃,可能会唤醒沉睡中的克苏鲁,或者更糟……可能会按预期工作。

标签: c++ c++20 designated-initializer


【解决方案1】:

成员按照它们在类定义中出现的顺序进行初始化,因此指定的初始化器不是那么相关,这也是

struct A { 
    const int & x = z; 
    int y = x;           // <- read of indeterminate value !
    int z = 42;          // <- doesn't really matter because y is initialized before ! 
};

int main() {
    return A{}.y;
}

出于同样的原因未定义。


另见cppreference的例子:

struct A {
  string str;
  int n = 42;
  int m = -1;
};
A{.m=21}  // Initializes str with {}, which calls the default constructor
          // then initializes n with = 42
          // then initializes m with = 21

这个例子其实是为了说明一些别的,但也说明了成员是如何按顺序初始化的。

【讨论】:

    猜你喜欢
    • 2020-07-20
    • 2020-01-13
    • 2016-05-15
    • 1970-01-01
    • 2018-09-16
    • 2020-01-13
    • 1970-01-01
    • 2012-12-24
    • 1970-01-01
    相关资源
    最近更新 更多