我使用的是C风格的结构,它没有任何构造函数,如下所示:
struct structName {
int mem1;
int mem2;
char mem3;
char mem4;
}
我正在创建这个结构的变量,我想将结构的所有成员初始化为零。我找到了以下方法。
struct structName structVar = {};
struct structName structVar = {0};
struct structName structVar = struct structName();
对于前两种方法,我的编译器正在为成员提供"缺少初始化程序"警告。
第三种方法在没有警告的情况下编译。
答案 0 :(得分:1)
首选方法应为:
之一structName structVar{};
structName structVar = {};
auto structName = structVar{};
存在细微的差异,但不会像示例
中的聚合那样这样做的另一个好处是,它为 structVar
的任何类型初始化structName
,或者如果它无法执行初始化,则会导致程序格式错误(代码不对“编译”(加上它不允许缩小)。
在您的具体示例中,structName
是一个agregate:
§8.5.1聚合[dcl.init.aggr]
(1)聚合是一个没有用户提供的数组或类(第9条) 构造函数(12.1),没有私有或受保护的非静态数据成员 (第11条),没有基类(第10条),也没有虚函数 (10.3)
我使用的初始化语法称为List-initialization:
§8.5.4列表初始化[dcl.init.list]
(1)列表初始化是 从braced-init-list初始化对象或引用。 [...]初始化列表可能为空。 [...]
对于我们的聚合,这意味着:
§8.5.1聚合[dcl.init.aggr]
(2)当初始化列表初始化聚合时,如 在8.5.4中指定,初始化列表的元素被视为 增加下标的聚合成员的初始化程序 或会员订单。每个成员都是从中复制初始化的 相应的初始化子句
(7)如果列表中的初始化子句子数少于 聚合中的成员,然后每个成员未明确初始化 应从其支撑或等于初始化器初始化,或者如果有的话 从空的初始化列表中不是大括号或大小写的 (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),ss.d为值 of ss.b [ss.a](即's')
[...]
结束例子]
因此所有这些都是有效的,并做同样的事情:
structName structVar = {};
structName structVar = {0};
structName structVar = {0, 0};
但是,如果聚合中至少有一个initializer-clauses
且少于成员,则gcc
和clang
会发出警告。可能是您打算初始化所有成员,但错过了一些。因此空的初始化列表是最安全的选择。
作为旁注,struct
不需要,并且通常不在声明中使用。所以替换这个:
struct structName structVar
使用:
structName structVar