初始化结构体的指定初始化方法

4

我知道在C99中可以使用指定初始化器来初始化结构,就像这样:

typedef struct
{
    char a;
    char b;
    int c;

} MyStruct;

MyStruct s = {.a = 1, .b = 2, .c = 3};

这段代码在我的C++编译器上无法运行,但是(俄罗斯)维基百科说它应该可以。

但出于某种奇怪的原因,像这样的代码也会编译(并且按预期工作):

typedef struct
{
    char a;
    char b;
    int c;

} MyStruct;


MyStruct arr[5];

int main(void)
{
    arr[0] = (MyStruct){.a = 1, .b = 2, .c = 0x332211};
}

我认为初始化应该只在对象创建时起作用,而不是之后。
这种行为是正常的,还是某种编译器怪癖?在C++中应该有效吗? 这个花括号里面到底是什么东西?一种临时的未命名结构体吗? 我正在使用Keil uVision 4(在C++模式下指定的初始化程序无法工作)。

1
你用的编译器是什么?gcc? - Yu Hao
1
请添加维基百科指定的链接。另外,您真的在询问两种语言(C和C ++)吗? - Daniel Daranas
3
这些是带有复合字面量的指定初始化器。在C语言中是有效的,但在C++中不是。[链接] (http://nickdesaulniers.github.io/blog/2013/07/25/designated-initialization-with-pointers-in-c/) - jrok
1
@Amomum:我看不懂俄语,但我在那个网页上没有看到任何关于指定初始化程序的例子。英文版正确地将它们提及为一种C构造,不存在于C++中。 - Mike Seymour
@MikeSeymour,链接错误 http://ru.wikipedia.org/wiki/Структура_(программирование)#C.2B.2B - Amomum
显示剩余4条评论
3个回答

6
指定的初始化器是C语言的一种构造,它们不是C++的一部分。因此,C++编译器在拒绝代码时是正确的,并且在两种情况下都应该这样做。
第二个构造是“复合字面量”,同样是C语言的一项功能,不是C++的一部分。因此,C++编译器应该拒绝它,而C99(或更新版本)编译器应该接受这两个片段。

4

指定初始化器(在第一个示例中)和复合字面量(在第二个示例中)都是在C99中引入的,C ++尚不支持它们。

然而,一些编译器可能作为扩展在C ++中支持这些功能。例如,gcc支持C ++中的复合字面量,但不支持指定初始化器。看起来您的编译器也是如此。


2
“指定初始化器”是C99的一个特性,但似乎clang和gcc在C++中作为扩展支持它们,尽管gcc文档声称不支持。如果我使用“-pedantic”标志用clang构建它,它会说:
warning: designated initializers are a C99 feature [-Wc99-extensions]

"并且 gcc 发出警告:"
 warning: ISO C++ does not allow C99 designated initializers [-Wpedantic]

在C++中,我们有构造函数可以让你以更清晰的方式初始化结构体。
第二个例子使用了复合字面量,这也是一个C99特性,并且被作为扩展支持。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接