为什么一致的实现表现不同 w.r.t。具有内部链接的不完整数组类型?
Why do conforming implementations behave differently w.r.t. incomplete array types with internal linkage?
示例代码(t0.c):
static int arr[ ];
int main( void )
{
return arr[ 0 ];
}
static int arr[ ] = { 0 };
调用:
$ gcc t0.c -std=c11 -Wall -Wextra
<nothing>
$ clang t0.c -std=c11 -Wall -Wextra
<nothing>
$ cl t0.c /std:c11 /Za
t0.c(1): error C2133: 'arr': unknown size
$ gcc t0.c -std=c11 -Wall -Wextra -pedantic
t0.c:1:12: error: array size missing in ‘arr’
$ clang t0.c -std=c11 -Wall -Wextra -pedantic
<nothing>
C11, 6.2.5 类型, 22:
An array type of unknown size is an incomplete type. It is completed, for an identifier of that type, by specifying the size in a later declaration (with internal or external linkage).
C11, 6.9.2 外部对象定义, 3:
If the declaration of an identifier for an object is a tentative definition and has internal linkage, the declared type shall not be an incomplete type.
C11,J.2 未定义行为,1:
An identifier for an object with internal linkage and an incomplete type is declared with a tentative definition (6.9.2).
问题:为什么一致的实现表现出不同的行为?哪一个行为正确?
根据引用的段落,特别是 6.9.2p3 和非规范的 J.2p1,代码显然违反了这些条款,因此可能不会出现在 严格符合的程序中 在 C standard:
的第 4p5 节中定义
A strictly conforming program shall use only those features
of the language and library specified in this International
Standard. It shall not produce output dependent on any
unspecified, undefined, or implementation-defined behavior, and
shall not exceed any minimum implementation limit
然而,实现可以自由定义在严格符合程序中不允许的扩展。使用此类扩展的程序是 符合第 4p6 节中定义的程序:
The two forms of conforming implementation are hosted and
freestanding. A conforming hosted implementation shall accept
any strictly conforming program. [ ... details of freestanding omitted ... ] A conforming
implementation may have extensions (including additional library
functions), provided they do not alter the behavior of any
strictly conforming program
根据编译器输出,似乎 MSVC 不支持此类扩展,但 gcc 和 clang 支持。
此外,当传递 -pedantic
标志时,gcc 会正确地禁用此功能,强制严格遵守。该 clang 不生成带有 -pedantic
的诊断似乎是一个错误。
示例代码(t0.c):
static int arr[ ];
int main( void )
{
return arr[ 0 ];
}
static int arr[ ] = { 0 };
调用:
$ gcc t0.c -std=c11 -Wall -Wextra
<nothing>
$ clang t0.c -std=c11 -Wall -Wextra
<nothing>
$ cl t0.c /std:c11 /Za
t0.c(1): error C2133: 'arr': unknown size
$ gcc t0.c -std=c11 -Wall -Wextra -pedantic
t0.c:1:12: error: array size missing in ‘arr’
$ clang t0.c -std=c11 -Wall -Wextra -pedantic
<nothing>
C11, 6.2.5 类型, 22:
An array type of unknown size is an incomplete type. It is completed, for an identifier of that type, by specifying the size in a later declaration (with internal or external linkage).
C11, 6.9.2 外部对象定义, 3:
If the declaration of an identifier for an object is a tentative definition and has internal linkage, the declared type shall not be an incomplete type.
C11,J.2 未定义行为,1:
An identifier for an object with internal linkage and an incomplete type is declared with a tentative definition (6.9.2).
问题:为什么一致的实现表现出不同的行为?哪一个行为正确?
根据引用的段落,特别是 6.9.2p3 和非规范的 J.2p1,代码显然违反了这些条款,因此可能不会出现在 严格符合的程序中 在 C standard:
的第 4p5 节中定义A strictly conforming program shall use only those features of the language and library specified in this International Standard. It shall not produce output dependent on any unspecified, undefined, or implementation-defined behavior, and shall not exceed any minimum implementation limit
然而,实现可以自由定义在严格符合程序中不允许的扩展。使用此类扩展的程序是 符合第 4p6 节中定义的程序:
The two forms of conforming implementation are hosted and freestanding. A conforming hosted implementation shall accept any strictly conforming program. [ ... details of freestanding omitted ... ] A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any strictly conforming program
根据编译器输出,似乎 MSVC 不支持此类扩展,但 gcc 和 clang 支持。
此外,当传递 -pedantic
标志时,gcc 会正确地禁用此功能,强制严格遵守。该 clang 不生成带有 -pedantic
的诊断似乎是一个错误。