结构成员顺序导致"non-trivial designated initializers not supported"错误

Struct member order causing "non-trivial designated initializers not supported" error

本文关键字:initializers not supported 错误 designated non-trivial 顺序 结构 成员      更新时间:2023-10-16

以前在这里和这里看到

我有以下结构:

struct myStruct {
    long int  mem0;
    int       mem1;
    int       mem2;
//  -- Place 1 --
    short int sh;
    -- Place 2 --  
    char      array[5];
//  -- Place 3 --
};

我尝试如下初始化它:

struct myStruct ms1 = {
      mem0 : 124,
      mem1 : 120,
      mem2 : 99,
      mem3 : 12,
};                      // Line 36

如果我将以下任何一行放置在位置2或位置3

    char      mem3;
    int       mem3;

我得到以下错误:

Azulejo-Main-Engine-1v2-4% g++ test2.cpp -o test2
test2.cpp: In function ‘int main()’:
test2.cpp:36:5: sorry, unimplemented: non-trivial designated initializers not supported
     };
     ^
Azulejo-Main-Engine-1v2-4% 

但是,如果我把它放在第1位,我的程序就会编译(并按预期执行)。你能解释一下为什么会这样吗?。

我正在尝试将C代码移植到C++中。如何防止这种错误?。我无法控制代码使用的结构声明。

Azulejo-Main-Engine-1v2-4% g++ --version
g++ (GCC) 5.2.0

"抱歉,未实现:<…>"总是意味着编译器还没有更新到允许这样做。这与未来是否允许、标准是否允许或是否合理无关。

正如评论中提到的,这不是有效的C++,这是一个编译器扩展。您可以通过将自己限制在有效的C++中来避免此类问题。如果您将-pedantic标志传递给GCC,GCC将诊断此扩展和许多其他扩展。如果您将-pedantic-errors标志传递给它,它将把这样的扩展视为一个硬错误。如果您看到您正在编写不可移植的C++,请更新您的代码使其可移植,方法如下:

struct myStruct ms1 = {
  124,
  120,
  99,
  12
};

这需要您将mem3放在mem2之后,或者通过

struct myStruct ms1 {};
ms1.mem0 = 124;
ms1.mem1 = 120;
ms1.mem2 = 99;
ms1.mem3 = 12;

它不需要mem3的任何特定位置,或者通过在myStruct中添加构造函数来获取mem0。。。CCD_ 8作为参数。


关于此扩展的复杂性的一些额外细节:

C++中结构的初始化通常以字段声明的任何顺序进行。这使得处理异常变得相当容易:字段可以按相反的顺序销毁。如果还没有建造完所有的田地,那么就从建造的最后一块田地开始销毁。

如果允许按任意顺序初始化字段,那么破坏就会变得复杂。给定struct myStruct ms1 { mem1: f(), mem0: g() };,如果g抛出异常,则要么mem1已经初始化并需要销毁,而mem0也没有被销毁,要么编译器重新排列初始化程序,这意味着g()f()之前被调用。前者在编译器中很难正确,后者则非常不直观。

对于普通的可销毁字段,可能会有一个特殊的例外,即当字段被销毁时,不需要运行用户代码,但它还没有实现。

如果将mem3放在mem2之后,那么问题就避免了:初始化的顺序与字段顺序完全匹配。