C
C言語Day 3

QUIZ: サイズ不定な配列型変数?

誰得クイズ

問:下記Cソースコードをコンパイルした場合、配列aはどのように初期化されるか?ファイルは下記2行のみからなるとする。

quiz.c
int a[];
int main() {}

≡≡≡≡≡≡≡≡≡≡c⌒っ゚Д゚)っ

⊂(゚Д゚⊂⌒`つ≡≡≡≡≡≡≡≡≡≡

解答

答:変数aは1要素の配列としてゼロ初期化される。つまり int a[1] = { 0 }; 相当となる。

この振る舞いはC言語特有の「仮定義(tentative definition)」とよばれる言語機能による。C99言語仕様 ISO/IEC 9899:1999、および対応する JIS X 3010:2003 よりそれぞれ引用。

ISO/IEC 9899:1999

6.9.2 External object definitions

2 A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static, constitutes a tentative definition. If a translation unit contains one or more tentative definitions for an identifier, and the translation unit contains no external definition for that identifier, then the behavior is exactly as if the translation unit contains a file scope declaration of that identifier, with the composite type as of the end of the translation unit, with an initializer equal to 0.

5 EXAMPLE 2 If at the end of the translation unit containing

int i[];

the array i still has incomplete type, the implicit initializer causes it to have one element, which is set to zero on program startup.

JIS X 3010:2003

6.9.2 外部オブジェクト定義

ファイル有効範囲のオブジェクトの識別子を,初期化子を使わず,かつ,記憶域クラス指定子なしか又は記憶域クラス指定子 static で宣言する場合,そのオブジェクトの識別子の宣言を仮定義(tentative definition)という。翻訳単位が,ある識別子に対する仮定義を一つ以上含み,かつその識別子に対する外部定義を含まない場合,その翻訳単位に,翻訳単位の終わりの時点での合成型,及び 0 に等しい初期化子をもったその識別子のファイル有効範囲の宣言がある場合と同じ規則で動作する。

例2. 翻訳単位が

int i[];

を含み,その翻訳単位の最後で,配列 i が依然として不完全型をもつ場合,配列 i は暗黙の初期化子によって一つの要素をもつようにされる。その要素にはプログラム開始時に 0 がセットされる。

で?

C言語ってムツカシイ ∩( ・ω・)∩