5

Sample code (t0.c):

static int arr[ ];

int main( void )
{
        return arr[ 0 ];
}

static int arr[ ] = { 0 };

Invocations:

$ 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 Types, 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 External object definitions, 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 Undefined behavior, 1:

An identifier for an object with internal linkage and an incomplete type is declared with a tentative definition (6.9.2).

Question: Why do conforming implementations show different behavior? Which one behaves correctly?

UPD1. Created https://bugs.llvm.org/show_bug.cgi?id=51319.

pmor
  • 5,392
  • 4
  • 17
  • 36
  • At first glance I'd say this is a plain old bug in clang. They forgot the special case for tentative definitions with internal linkage. Out of curiosity, does clang's behavior change if you add `-fno-common` to the command line? – zwol Aug 03 '21 at 12:11
  • @zwol doesn't seem like it does: https://godbolt.org/z/3bTqs64PW – mediocrevegetable1 Aug 03 '21 at 12:15

1 Answers1

2

Based on the quoted passages, particularly 6.9.2p3 and the non-normative J.2p1, it seems clear that the code violates these clauses and therefore may not appear in a strictly conforming program defined in section 4p5 of the C standard:

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

Implementations are however free to define extensions that would not be allowed in a strictly conforming program. A program using such extensions is a conforming program as defined in section 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

Based on the compiler output, it appears that MSVC does not support such an extension but gcc and clang do.

Additionally, gcc correctly disables this feature when the -pedantic flag is passed, forcing strict compliance. That clang does not generate a diagnostic with -pedantic appears to be a bug.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • Thanks. If 6.9.2p3 prohibits "internal linkage" case, then why 6.2.5p22 does mention "internal linkage" in parentheses? – pmor Aug 03 '21 at 12:23
  • At the beginning the 6.2.5p22 talks about arrays. Hence, the "it" == "array" and "internal linkage" in parentheses is related to arrays. Or do I miss something? – pmor Aug 03 '21 at 12:46
  • I guess that extension cannot cancel the existing standard requirements. I guess that extension is a feature, which is 1) on top of the existing features, 2) does not break the existing features. In our case we see that "no-diagnostics" extension supported by compiler implementations (presented above) cancels the standard requirement 6.9.2p3. Hence, such compiler implementations are non-conforming. How can you comment on that? – pmor Aug 06 '21 at 13:59
  • @pmor The purpose of an extension is to allow features that would not otherwise be allowed by the standard, and this is one of those cases. The fact that clang does not generate a warning in pedantic mode I would consider a bug, but gcc is still conforming. – dbush Aug 06 '21 at 14:20