名字写的这么绕,其实就是常用的struct initializer的写法{0},老是这么 用,习焉不察矣,今天别人问起来。想起来差了老半天C/C++标准。终于把这 个问题搞清楚了。这里以C99标准为准–—C++标准的相关部分是从C标准里面 抄来的。
很显然,标准里面对不完全的initializer list的行为是有规定的,相关表述 如下(下面引文全部引自C99标准草稿):
[6.7.8.21] If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.
也就是说,类似这样:
struct {int a;int b;} aa = {0};
的写法是完全没问题的,并且会把a,b都zeroing(a是从initializer literal 来的,b是上述因为规定的)。
有一个基本常识是,C里面的非复合类型(我自己造的词,那么个意思,大家别 细究了)都可以用0初始化,所以{0}初始化上面例子中类似的结构是没问题的, 有的人的疑问在于如果struct的第一个元素是struct怎么办。标准规定了这种 情况下的行为:
[6.7.8.20] If the aggregate contains elements or members that are aggregates or unions, or if the first member of a union is an aggregate or union, these rules apply recursively to the subaggregates or contained unions. If the initializer of a subaggregate or contained union begins with a left brace, the initializers enclosed by that brace and its matching right brace initialize the elements or members of the subaggregate or the first member of the contained union. Otherwise, only enough initializers from the list are taken to account for the elements or members of the subaggregate or the first member of the contained union; any remaining initializers are left to initialize the next element or member of the aggregate of which the current subaggregate or contained union is a part.
这段话很长很绕,简单的说,如果aggregate(这里简单理解为struct,准确的 表述去看标准)的某个元素是aggregate,就按照普通的aggregate初始化规则找 到该aggregate的初始化列表开始的地方,如果是大括号扩着的,就用那个括 号里面的list初始化这个aggregate,否则就从这里开始找到"足够"的条目给 自己来initialize,剩下的给别人用。
以这个例子来说:
struct {struct {int a;int b;} aa;int c;} _a = {1 ,2};
struct的第一个元素是struct,initializer它相应的位置没有{…}这样的东 东,而是个"1",那它就从这里拿"足够"的initializer来初始化自己,就是把 "1,2",拿来初始化a,b了。所以结果就是a == {{1,2},0};
这样,对上面这个结构用{0}初始化就很容易理解了。