我有以下结构:
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
答案 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
,则可以避免问题:初始化顺序与字段顺序完全匹配。