C++ 中的聚合初始化安全性
假设我有以下结构:
struct sampleData
{
int x;
int y;
};
并且在使用时,我想将 sampleData
类型的变量初始化为已知状态。
sampleData sample = { 1, 2 }
后来,我决定需要将其他数据存储在我的 sampleData
结构中,如下所示:
struct sampleData
{
int x;
int y;
int z;
};
据我了解,我的前 z
数据结构中留下了两个字段初始化仍然是有效的语句,并且将被编译。用默认值填充缺少的字段。
这种理解正确吗?我最近一直在使用 Ada,它也允许聚合初始化,但会将类似的问题标记为编译错误。假设我对上面的 C++ 代码的假设是正确的,是否有一种语言结构可以将缺少初始化值识别为错误?
Suppose I have the following struct:
struct sampleData
{
int x;
int y;
};
And when used, I want to initialize variables of sampleData
type to a known state.
sampleData sample = { 1, 2 }
Later, I decide that I need additional data stored in my sampleData
struct, as follows:
struct sampleData
{
int x;
int y;
int z;
};
It is my understanding that the two field initialization left over from my pre-z
data structure is still a valid statement, and will be compiled., populating the missing fields with default values.
Is this understanding correct? I have been working recently in Ada, which also allows aggregate initialization, but which would flag a similar issue as a compilation error. Assuming that my assumptions about the C++ code above are correct, is there a language construct which would recognize missing initialization values as an error?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
仅聚合类支持以这种方式初始化变量。
如果您添加构造函数,那么问题就会消失,但是您需要稍微更改语法,并且您将失去将
struct
存储在union
中的能力(除其他外)。添加
z
(并更改构造函数)会将sample( 1, 2 )
标记为编译错误。Initialising variables that way is only supported with Aggregate Classes.
If you add constructor(s) then then problem goes away, but you'll need to change the syntax a little and you lose the ability to store the
struct
in aunion
(among other things).Adding
z
(and changing the constructor) will marksample( 1, 2 )
as a compile error.是的,您离开初始化列表的任何元素都将初始化为零(对于 POD 标量类型)或使用其默认构造函数(对于类)。
此处引用了 C 标准中的相关语言:
我确信有人比我更有动力,可以在 C++ 规范之一中找到相应的语言...
请注意,这意味着 POD 标量元素的初始化就像您编写“= 0”一样。这意味着它会正确地将指针初始化为 NULL 并浮点数为 0.0,即使它们的表示形式并非恰好是全零字节。它还意味着它是递归地工作的;如果您的结构包含一个结构,则内部结构也将被正确初始化。
Yes, any elements you leave off of the initialization list will be initialized to zero (for POD scalar types) or using their default constructor (for classes).
The relevant language from the C standard is quoted here:
I am sure someone more motivated than I could find the corresponding language in one of the C++ specs...
Note that this implies that POD scalar elements are initialized as if you wrote "= 0". Which means it will correctly initialize pointers to NULL and floats to 0.0 even if their representations do not happen to be all-zero bytes. It also implies that it works recursively; if your struct contains a struct, the inner struct will be properly initialized as well.
作为 Nemo 使用 C 标准的回答的后续内容,以下是 C++03 标准的内容:
§8.5.1/7:
§8.5/5:
As a followup to Nemo's answer with the C standardese, here is what the C++03 standard says:
§8.5.1/7:
§8.5/5:
为什么不使用
?
但是您仍然会遇到
z
被初始化为不可预测值的问题,因此最好定义一个构造函数,将所有变量设置为明确定义的值。Why not use
?
But you'd still run into the problem of
z
being initialized to an unpredictable value, so it's better to define a constructor which sets all variables to well defined values.