结构成员订单导致"非平凡的指定初始化程序不受支持"错误

时间:2015-11-16 12:38:28

标签: c++

之前见过herehere

我有以下结构:

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

1 个答案:

答案 0 :(得分:2)

“对不起,未实现:< ...>”始终意味着编译器尚未更新以允许这样做。这无论将来是否允许,标准是否允许,或者是否有意义。

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

-pedantic-errors

要求您在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添加构造函数。

有关此扩展程序并发症的一些额外详细信息:

C ++中结构的初始化通常以声明字段的顺序发生。这使得处理异常变得相当容易:可以按相反的顺序销毁字段。如果还没有构建所有字段,则在最后构建的字段处开始销毁。

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

可以为一些简单的可破坏字段做一个特殊的例外,当字段被销毁时不需要运行用户代码,但尚未实现。

如果您在f()之后放置mem3,则可以避免问题:初始化顺序与字段顺序完全匹配。