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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With