名字寫的這麼繞,其實就是常用的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}初始化就很容易理解了。
Org version 7.8.05 with Emacs version 23
摘自 卡列寧的微笑