2016-08-30 49 views
0

我一直在找周圍爲什麼這編譯:爲什麼在C中爲init結構工作? struct x_ tmp = {{{{}}}};

struct x_ { 
    char a[10]; 
    int b; 
}; 

struct x_ tmp = {{{{0}}}}; 

我們可能有一箇舊版本的編譯,所以{0}可能無法正常工作和{{0}}應該被使用,但沒有看到這{{{{0}}}}任何地方。 參見GCC錯誤這裏:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119

由於 彼得

+0

MSVC說「太多初始化程序」,並且在'struct'定義之後留下了語法錯誤no';'。 –

+0

@WeatherVane gcc,只需修復它;) – Serge

+0

您可以通過'gcc --version'確切確定哪個版本的gcc。 –

回答

-2

當初始化包含數組的結構,既可以初始化的第一個元素(具有設置爲0默認的其餘部分),也可以提供的初始化每個值。在這種情況下,使用字符串初始化爲a陣列樣式初始化爲所有成員提供值,例如,

struct x_ tmp = { .a="" }; /* using string initialization of a */ 

struct x_ tmp = {{0},0}; /* using array initialization format */ 

未能識別某一特定領域,或提供一個初始化的所有成員都將產生圍繞一個標量初始化和缺場的初始化括號編譯器警告,同時默認初始化值爲0

與利用/輸出

#include <stdio.h> 

struct x_ { 
    char a[10]; 
    int b; 
}; 

int main (void) { 

    struct x_ tmp = { .a="" }; /* using string initialization of a */ 
    struct x_ tmq = {{0},0}; /* using array initialization format */ 

    printf ("\n tmp.a : '%s', tmp.b : %d\n", tmp.a, tmp.b); 
    printf ("\n tmq.a : '%s', tmq.b : %d\n", tmq.a, tmq.b); 

    return 0; 
} 

例如實施例

$ ./bin/struct_init 

tmp.a : '', tmp.b : 0 

tmq.a : '', tmq.b : 0 
+0

也許downvoter將具有完整性來識別示例中的技術不準確性,但是他們可能不會。 –

+0

問題不是關於正確的語法,儘管'tmp = {0};'在這種情況下也是正確的,但是爲什麼'gcc'沒有編譯'tmp = {{{{}}}};'沒有錯誤。我認爲這是downvote的原因 – Serge

+0

該bug報告是關於單成員數組初始化提交的。沒有任何參數可以通過'struct example ex = {0};'初始化'struct example {int foo [2];};',但在問題中不是'tmp'。 –

1

我將問題解釋爲詢問GCC是否正確接受指定類型的對象的指定初始化程序。爲了解決這個問題,我將引用C2011標準的6.7.9節。

首先,以下既適用於初始化爲整體結構,並內的第一構件的初始化:

[...]的初始值設定爲一個對象,其具有聚合或聯合類型應是元素或命名成員的初始化符的大括號包含列表。

我們則有:

每個括號內的初始化列表中有相關​​的當前對象。當前對象的子對象按照 的順序初始化爲當前對象的類型:數組元素以下標順序遞增,結構成員以聲明順序[...]。

......後來......

如果聚集或聯合包含的元素或成員是聚集或工會,這些規則遞歸適用於subaggregates或包含工會。如果子集或包含的聯合的初始化器以左大括號開始,那麼大括號和其右括號所包含的初始化器將初始化子集或包含的聯合的元素或成員。

在這些,我們已經建立了作爲一個初始化整個結構的整體{{{{0}}}}{{{0}}}作爲其第一個成員,a一個初始化,並{{0}}作爲a[0]的初始化。問題歸結爲最後的配對是否有效。如果是,那麼其他人也是有效的。

這可能帶有對此事:

爲標量的初始化應是一個單一的表達,任選包含在括號

(強調增加)。這可以解釋爲指定a[0]的初始值設定項可以用大括號括起來,即{0},因爲a[0]確實是一個標量。我不相信這就是預期的解釋,但我現在不會準備好接受GCC的過錯。

但是,我不接受{{0}}作爲大括號中的單個表達式,因此我不接受它是a[0]的有效初始值設定項。我推測 GCC接受它作爲規則的不適當的遞歸應用的結果,允許標量初始化器被大括號包圍。

對於它的價值,GCC 4.4.7並默認發出關於構建兩個警告:

i.c:7: warning: braces around scalar initializer 
i.c:7: warning: (near initialization for ‘tmp.a[0]’) 
i.c:7: warning: braces around scalar initializer 
i.c:7: warning: (near initialization for ‘tmp.a[0]’) 

顯然,然後,有人認爲額外的括號是有問題的,但海灣合作委員會的文件沒有提到接受這在支持的語言擴展中形成。那麼,至少有一個文檔錯誤。

相關問題