开始前:
Let me point out that a lot of the confusion around this syntax comes because in C and C++ you can use the = {0}
syntax to initialize all members of a C-style array to zero! See here: https://en.cppreference.com/w/c/language/array_initialization. This works:
// z has type int[3] and holds all zeroes, as: `{0, 0, 0}`
int z[3] = {0}
But, that syntax does not work the same for structs, which are entirely different animals than C-style arrays.
See also my follow-up question I asked after writing this answer below: Why doesn't initializing a C++ struct to = {0}
set all of its members to 0?
回到答案:
我想通了:要使其编译,只需删除零:
myStruct _m1 = {0}
myStruct _m1 = {}
现在它可以编译了。但是,我运行了一堆测试来检查我在
struct_initialization.cpp文件中的一些内容,在我的
eRCaGuy_hello_world存储库中,它并没有将结构体的所有元素初始化为
零!相反,它将结构体初始化为其
默认值。要运行我的测试并自己查看,请克隆我的上面的存储库并运行
eRCaGuy_hello_world/cpp/run_struct_initialization.sh
。
假设你有这个结构体:
typedef struct
{
int num1 = 100;
int num2 = -100;
int num3;
int num4 = 150;
} data_t;
注意:上面的typedef
是在我测试这些东西时使用C而不是C++的遗留问题(当然,在C中不允许使用默认结构值)。对于C ++,最好使用以下方法:
{{注意:上面的typedef是我在测试这些东西时在C而不是C++中使用的(尽管在C中不允许使用默认结构值)。对于C ++,最好使用以下方法:}}
struct data_t
{
int num1 = 100;
int num2 = -100;
int num3;
int num4 = 150;
};
所以请忽略我在下面不必要地使用typedef
定义结构体。
无论如何,如果我声明上述任何一个data_t
结构体,然后执行以下操作:
data_t d2 = {};
printf("d2.num1 = %i\nd2.num2 = %i\nd2.num3 = %i\nd2.num4 = %i\n\n",
d2.num1, d2.num2, d2.num3, d2.num4);
输出将会是:
d2.num1 = 100
d2.num2 = -100
d2.num3 = 0
d2.num4 = 150
我甚至不确定d2.num3
是否为零,是因为它被初始化为零还是因为它未被初始化而那个内存位置碰巧包含零。
如此解释:https://en.cppreference.com/w/cpp/language/zero_initialization,你也可以这样做:
myStruct _m1{};
在上面的示例中,这段代码:
data_t d2{};
printf("d2.num1 = %i\nd2.num2 = %i\nd2.num3 = %i\nd2.num4 = %i\n\n",
d2.num1, d2.num2, d2.num3, d2.num4);
...将产生与我上面展示的输出完全相同的结果。
即使在设置结构体为= {0}
有效的情况下,例如:
// Does NOT do what I expected! Only sets the FIRST value in the struct to zero!
// The rest seem to use default values.
data_t d3 = {0};
printf("d3.num1 = %i\nd3.num2 = %i\nd3.num3 = %i\nd3.num4 = %i\n\n",
d3.num1, d3.num2, d3.num3, d3.num4);
...输出仍然不符合我的期望,因为它只将{{第一个}}值设为零!(我不明白为什么):
d3.num1 = 0
d3.num2 = -100
d3.num3 = 0
d3.num4 = 150
然而,在C语言风格的数组中(而不是结构体),这些语义是有效的。请参考此处的答案(
如何将数组的所有成员初始化为相同的值?)。因此,以下这两行代码在使用C ++时都可以将C风格数组的所有元素设置为零:
uint8_t buffer[100] = {0}; // sets all elements to 0 in C OR C++
uint8_t buffer[100] = {}; // sets all elements to 0 in C++ only (won't compile in C)
因此,经过大量实验后,以下几种方式似乎是唯一的用于在C++中对结构体进行零初始化的方法。如果您知道其他方法,请在此处进行评论或留下您自己的答案。
C++中唯一可能的对结构体进行零初始化的方法有:
Be explicit:
// C-style typedef'ed struct
typedef struct
{
int num1 = 100;
int num2 = -100;
int num3;
int num4 = 150;
} data_t;
// EXPLICITLY set every value to what you want!
data_t d1 = {0, 0, 0, 0};
// OR (using gcc or C++20 only)
data_t d2 = {.num1 = 0, .num2 = 0, .num3 = 0, .num4 = 0};
Use memset()
to force all bytes to zero:
data_t d3;
memset(&d3, 0, sizeof(d3));
Set all default values to zero in the first place:
// C-style typedef'ed struct
typedef struct
{
int num1 = 0;
int num2 = 0;
int num3 = 0;
int num4 = 0;
} data_t;
// Set all values to their defaults, which are zero in
// this case
data_t d4 = {};
// OR
data_t d5{}; // same thing as above in C++
// Set the FIRST value only to zero, and all the rest
// to their defaults, which are also zero in this case
data_t d6 = {0};
Write a constructor for the C++ struct
struct data
{
int num1;
int num2;
int num3;
int num4;
data() :
num1(0),
num2(0),
num3(0),
num4(0) {}
};
data d7;
struct data
{
int num1;
int num2;
int num3;
int num4;
data()
{
num1 = 0;
num2 = 0;
num3 = 0;
num4 = 0;
}
};
data d8;
Use a struct with no default values, and make your object you create from it static
typedef struct
{
int num1;
int num2;
int num3;
int num4;
} data_t;
// `static` forces a default initialization of zero for each
// value when no other default values are set
static data_t d9;
So, if you have a struct with non-zero default values, and you want to zero all values, you must do it EXPLICITLY! Here are some more ways:
struct data
{
int num1 = 1;
int num2 = 7;
int num3 = -10;
int num4 = 55;
};
constexpr data DATA_ALL_ZEROS = {0, 0, 0, 0};
data d13 = DATA_ALL_ZEROS;
struct data
{
int num1 = 1;
int num2 = 7;
int num3 = -10;
int num4 = 55;
zero()
{
num1 = 0;
num2 = 0;
num3 = 0;
num4 = 0;
}
};
data d14;
d14.zero();
重要的结论是:这三种写法:
data_t d{}
、
data_t d = {}
和
data_t d = {0}
都不能将结构体的所有成员都设置为零!
data_t d{}
会将所有值设置为结构体中定义的默认值。
data_t d = {}
也会将所有值设置为默认值。
data_t d = {0}
只会将第一个值设置为零,其他值仍然是默认值。
因此,请
明确指定需要的初始化值!
请注意,我写的以上主要结论似乎与
cppreference.com上的文档相矛盾,这促使我提出了
这个后续问题,对我的理解非常有帮助!
更深入的了解
- 最有用的:我的后续问题:为什么将C++结构体初始化为
= {0}
不能将其所有成员都设置为0?
参考资料:
- 非常有用:
- https://en.cppreference.com/w/cpp/language/zero_initialization(零初始化)
- https://en.cppreference.com/w/cpp/language/aggregate_initialization(聚合初始化)
- https://en.cppreference.com/w/cpp/language/value_initialization(值初始化)
- 非常有用:将数组(而不是结构体)的所有成员初始化为相同的值:
- 如何将数组的所有成员初始化为相同的值?
- [仅适用于gcc] 如何将数组的所有成员初始化为相同的值?
- https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/cpp/struct_initialization.cpp
- 克隆此存储库并使用
cpp/run_struct_initialization.sh
运行代码
相关:
- 在结构体中初始化默认值
- *****[我自己的答案,演示了在任何函数中修改结构体/重新分配成员的聚合方式:
leds [0] = {10, 20, 30, 40, 50};
] Arduino堆栈交换:初始化结构体数组