Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Strangely enough (or perhaps not so strangely...) it looks to me like gcc is correct to accept this.</p> <p>If this was declared <code>static</code> instead of <code>extern</code>, then it would have internal linkage, and §6.9.2/3 would apply:</p> <blockquote> <p>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.</p> </blockquote> <p>If it didn't specify any storage class (<code>extern</code>, in this case), then §6.7/7 would apply:</p> <blockquote> <p>If an identifier for an object is declared with no linkage, the type for the object shall be complete by the end of its declarator, or by the end of its init-declarator if it has an initializer; in the case of function arguments (including in prototypes), it is the adjusted type (see 6.7.5.3) that is required to be complete.</p> </blockquote> <p>I either of these cases, <code>void</code> would not work, because (§6.2.5/19):</p> <blockquote> <p>The void type [...] is an incomplete type that cannot be completed.</p> </blockquote> <p><em>None</em> of those applies, however. That seems to leave only the requirements of §6.7.2/2, which seems to allow a declaration of a name with type <code>void</code>:</p> <blockquote> <p>At least one type specifier shall be given in the declaration specifiers in each declaration, and in the specifier-qualifier list in each struct declaration and type name. Each list of type specifiers shall be one of the following sets (delimited by commas, when there is more than one set on a line); the type specifiers may occur in any order, possibly intermixed with the other declaration specifiers.</p> <ul> <li>void</li> <li>char</li> <li>signed char</li> </ul> <p>[ ... more types elided]</p> </blockquote> <p>I'm not sure that's really intentional -- I suspect the <code>void</code> is really intended for things like derived types (e.g., pointer to void) or the return type from a function, but I can't find anything that directly specifies that restriction.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. COMy reading of §6.9.2 is exactly the opposite of yours: 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. Doesn't that mean this is NOT a tentative definition and thus we an incomplete type is NOT allowed? Comeau, IMO, correctly complains.
      singulars
    2. CO@dirkgently: This is definitely not a tentative definition, which is defined as (§6.9.2/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*." I don't see anything that says an incomplete type isn't allowed just because it's not a tentative definition though.
      singulars
    3. COThe ambiguity between gcc and msvc seems to be in interpretation of ***§6.2.5.19***, If `void` is an Incomplete type which can never be completed, then the argument boils down to should `extern` be allowed to be applied on an Incomplete type which can never be complete,I believe it leaves room for implementation interpretation.Either ways, there will be an error for every compiler, just whether error is emitted during compilation or linking is what can differ & seems probably an edge case which they wouldnt want too many hassles about.
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload