如果我有一个常见的linux结构,如:
struct sockaddr_in
{
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
unsigned char __pad[__SOCK_SIZE__ - sizeof(short int)
- sizeof(unsigned short int) - sizeof(struct in_addr)];
};
#define sin_zero __pad
我执行聚合初始化:
struct sockaddr_in my_addr = { 0 };
为什么将每个成员初始化为0?
我的意思是:文档说:
如果初始化子句的数量小于 成员或初始化子句完全是空的,剩下的 成员由他们的大括号或相等的初始化程序初始化,如果 在类定义中提供,否则(从C ++ 14开始)为空 列表,执行值初始化。
让它变得简单:为什么这段代码打印0?
struct sockaddr_in my_addr = {2, 2}; // initialize sin_family and sin_port to 2, everything else value-initialized
my_addr = {0};
std::cout << my_addr.sin_port; // Why is this 0?
答案 0 :(得分:2)
draft C++14 standard部分8.5.4
列表初始化中包含了这一点,其中包含:
对象或类型T的引用的列表初始化定义如下:
并包括:
如果T是聚合,则执行聚合初始化(8.5.1)。
并有以下示例:
struct S2 {
int m1;
double m2, m3;
}
S2 s21 = { 1, 2, 3.0 }; // OK
S2 s22 { 1.0, 2, 3 }; // error: narrowing
S2 s23 { }; // OK: default to 0,0,0
和8.5.1
聚合,其中包含:
如果列表中的初始化子句数少于 聚合成员,然后是每个成员 未明确初始化的应从其初始化 支撑或等于初始化器,或者,如果没有 brace-or-equalinitializer,来自空的初始化列表(8.5.4)。 [ 例如:
struct S { int a; const char* b; int c; int d = b[a]; }; S ss = { 1, "asdf" };
将ss.a初始化为1,ss.b使用“asdf”,ss.c初始化,值为an 表达式int {}(即0)
请注意8.5.4
在C ++ 11中略有不同,它说:
对象或类型T的引用的列表初始化定义为 如下:
如果初始化列表没有元素而T是一个类 使用默认构造函数输入,该对象是值初始化的。
否则,如果T是聚合,则执行聚合初始化 (8.5.1)。
答案 1 :(得分:1)
为什么将每个成员初始化为0?
因为这是C在初始化结构时所做的事情,而C ++对于兼容性的聚合初始化也是如此。
这样做是因为它更方便(它通常是你想要的那些你没有给出明确价值的会员)而且更安全(它没有这样做)留下危险的未初始化的变量。)如果你真的希望结构的其他成员保持未初始化,你可以这样做:
struct sockaddr_in s; // entirely uninitialized
s.sin_family = 0; // only initialize one member