web-dev-qa-db-ja.com

空のイニシャライザリストは有効なCコードですか?

{0}を使用してstructまたはarrayを初期化することは一般的ですが、最初のフィールドがスカラー型でない場合を考慮してください。 struct Personの最初のフィールドが別のstructまたは配列である場合、この行はエラー(error: missing braces around initializer)になります。

struct Person person = {0};

少なくともGCCでは、同じことを実行するために空の初期化リストを使用できます

struct Person person = {};

しかし、これは有効なCコードですか?

また、この行は同じ動作、つまりゼロで初期化されたstructを提供することが保証されていますか?

struct Person person;
36
Marcus Ahlberg

いいえ、空の初期化子リストは許可されていません。これは、-std=c99 -pedanticでコンパイルするときにGCCでも表示できます。

a.c:4: warning: ISO C forbids empty initializer braces

その理由は、文法が 2011 ISO C Standard の§6.7.9で定義されている方法にあります:

initializer:
         assignment-expression
         { initializer-list }
         { initializer-list , }
initializer-list:
         designation(opt) initializer
         initializer-list , designation(opt) initializer

その定義によれば、initializer-listには少なくとも1つの初期化子が含まれている必要があります。

42
interjay

C99標準によると、空の初期化リストを使用した配列の作成は禁止されています。以前の回答では、文法がこのケースを説明していないことがわかります。


しかし、初期化せずに配列を宣言するとどうなりますか?まあ、それはあなたが使うコンパイラに依存します。この簡単な例を見てみましょう:int arr[5] = {}

[〜#〜] gcc [〜#〜]

デフォルトでは、このコードをコンパイルしようとすると、gccwarnings/errorsを生成しません。でもない-Wall、 だが -Wpedanticします。

warning: ISO C forbids empty initializer braces

しかし、とにかくgccは、明示的に指定した場合とまったく同じように、配列のメンバーを0で埋めますint arr[5] = {0}アセンブリの出力 godbolt を参照してください。

[〜#〜] clang [〜#〜]

ただし、デフォルトではこのケースに関する警告は表示されませんが、オプション-Wgnu-empty-initializerは:

warning: use of GNU empty initializer extension

Clangは異なるアセンブリコード godbolt を生成しますが、動作は同じです。

2
funnydman