Why does gcc allow extern declarations of type void? Is this an extension or
standard C? Are there acceptable uses for this?
I am guessing it is an extension, but I don’t find it mentioned at:
http://gcc.gnu.org/onlinedocs/gcc-4.3.6/gcc/C-Extensions.html
$ cat extern_void.c
extern void foo; /* ok in gcc 4.3, not ok in Visual Studio 2008 */
void* get_foo_ptr(void) { return &foo; }
$ gcc -c extern_void.c # no compile error
$ gcc --version | head -n 1
gcc (Debian 4.3.2-1.1) 4.3.2
Defining foo as type void is of course a compile error:
$ gcc -c -Dextern= extern_void.c
extern_void.c:1: error: storage size of ‘foo’ isn’t known
For comparison, Visual Studio 2008 gives an error on the extern declaration:
$ cl /c extern_void.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
extern_void.c
extern_void.c(1) : error C2182: 'foo' : illegal use of type 'void'
Strangely enough (or perhaps not so strangely…) it looks to me like gcc is correct to accept this.
If this was declared
staticinstead ofextern, then it would have internal linkage, and §6.9.2/3 would apply:If it didn’t specify any storage class (
extern, in this case), then §6.7/7 would apply:I either of these cases,
voidwould not work, because (§6.2.5/19):None 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
void:I’m not sure that’s really intentional — I suspect the
voidis 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.