int arr[];
is a tentative definition there.
Clause 6.9.2, paragraph 2 says:
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
.
and example 2 in paragraph 5 of that clause clarifies:
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.
So at the end of the translation unit, your array arr
has type int[1]
. Before the end, its type is incomplete, hence sizeof
doesn't work, since in main
, the array type is still incomplete.
Accessing arr[1]
invokes undefined behaviour, since arr
has only one element.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…