Is this code correct?
extern "C" extern int x; // 1
extern extern "C" int y; // 2
extern "C" extern "C" int z; // 3
int main() { }
gcc rejects 1 and 2 as syntax errors and accepts 3. clang accepts all three but gives a duplicate-declaration-specifier warning about them all.
Maybe relevant is C++17 [dcl.stc]/5:
The
extern
specifier can be applied only to the names of variables and functions. Theextern
specifier cannot be used in the declaration of class members or function parameters. For the linkage of a name declared with anextern
specifier, see 6.5. [Note: Theextern
keyword can also be used in explicit-instantiations and linkage-specifications, but it is not a storage-class-specifier in such contexts. —end note ]
extern extern "C"
is not valid syntax, as extern "C"
is not a specifier and thus cannot occur in a decl-specifier-seq. Instead extern "C"
can only appear as part of a linkage-specification, for which the syntax is
extern
string-literal{
declaration-seq(opt)}
extern
string-literal declaration
Thus, extern "C"
must occur first.
Also, extern "C" extern
is not valid either, according to [dcl.link]/7:
A declaration directly contained in a linkage-specification is treated as if it contains the
extern
specifier (10.1.1) for the purpose of determining the linkage of the declared name and whether it is a definition. Such a declaration shall not specify a storage class.
(extern
is a storage class specifier.)
It doesn't seem that there is any rule forbidding extern "C" extern "C"
, though.