Consider the following translation unit:
extern "C" int x = 1;
I know that C-mangling an int
doesn't mean much; and that int x = 1
already guarantees external linkage, but this should work. Which it does; the thing is, GCC warns about using it, while clang doesn't: See this on GodBolt.
- Which compiler is "right"?
- How strongly, if it all would you advise avoiding such code?
CodePudding user response:
According to the standard at [dcl.link.2]
Linkage between C and non-C code fragments can be achieved using a linkage-specification:
linkage-specification:
extern string-literal { declaration-seq }
extern string-literal declaration
Both brace-enclosed and as a prefix to a single declaration are valid.
Which compiler is correct? I'd say both, as they both accept the code and do the correct thing with it.
GCC's warning is just that, a warning. This is the same kind of warning as a "named parameter is not used anywhere": Information about something unusual, but not affecting the behavior of the program.
CodePudding user response:
Both compilers are correct to compile the code without error.
gcc's warning 'x' initialized and declared 'extern'
makes sense as well. "extern" declarations, including extern "C"
ones, usually go in header files. Initializing in the header file will get you a multiple-definitions error at link time.
If you use the usual pattern, gcc will not give you any warning:
(in header) extern "C" int x;
(in one source file) int x = 1;
Your question says that you're doing this inside one compilation unit. That's not illegal under the language rules, but it is very sketchy.
Either you aren't using the variable in any other compilation unit (in which case it doesn't need linkage at all, let alone "C" linkage) or else you are repeating the declaration in other compilation units, which risks having a mismatch on the type or language linkage.
Putting declarations in header files in a good practice because it prevents type mismatch across compilation units, which is instant undefined behavior.