为何C++中my_type_t需用双大括号初始化,而C中单大括号即可?
C与C++中匿名结构体联合初始化的语法差异原因
你定义的my_type_t是包含匿名结构体的联合类型,C和C++初始化时的语法差异源于两者对聚合类型初始化的规则不同:
代码场景回顾
C++中必须使用双大括号才能正确初始化:
#include <iostream> #include "types.h" int main() { my_type_t t = { { .bla = 23, .sab = 0 } }; std::cout << "BLA: " << t.bla << "\n"; return 0; }
对应的头文件types.h内容:
#ifndef _TYPES_H_ #define _TYPES_H_ #include "stdint.h" extern "C" { typedef union my_type { struct { uint32_t bla : 8; uint32_t sab : 8; }; struct { uint32_t sabbla: 16; }; uint16_t raw; } my_type_t; } #endif
在C中直接用单大括号即可:
#include "types.h" int main() { my_type_t t = { .bla = 23, .sab = 0 }; return 0; }
如果在C++中尝试单大括号初始化,会触发编译错误:
main.cpp:6:41: error: too many initializers for ‘my_type_t’ {aka ‘my_type’} 6 | my_type_t t = { .bla = 23, .sab = 0 }; | ^
差异原因
C的初始化规则:
在C标准中,联合里的匿名结构体被视为联合"直接成员"的一部分。初始化联合时,C允许直接针对第一个匿名结构体的成员写初始化器,省略外层表示联合本身的大括号——编译器会自动将这些初始化器关联到联合的第一个匿名结构体成员。C++的初始化规则:
C++对聚合类型的初始化要求更严格:- 联合属于聚合类型,第一层大括号对应联合对象本身。
- 匿名结构体是联合的子聚合成员,要初始化这个子成员,必须用第二层嵌套大括号明确表示"初始化联合内部的这个匿名结构体"。
- 如果只用单大括号,C++编译器会认为你给联合本身提供了多个初始化器,但联合只能存储一个成员,无法接受多个初始化器,因此抛出"初始化器过多"的错误。
另外,C++中的匿名结构体本质是无名字的结构体子对象,必须通过嵌套初始化明确指向它,这和C允许的"扁平化"初始化逻辑完全不同。
内容的提问来源于stack exchange,提问作者binaryBigInt
相关产品推荐
相关产品推荐

