In a file, I have this macro:
#if defined(__cplusplus)
#define EXTERN_C extern "C"
#else
#define EXTERN_C extern
#endif
But searching on the web, it doesn't seem typical for such macros to have an extern
on the C path (though some examples exist). They generally come in pairs more akin to EXTERN_C_BEGIN
and EXTERN_C_END
to wrap up a group of declarations...and are a no-op in C builds.
But this means in a header file, you wind up having to write:
EXTERN_C_BEGIN
extern int x; /* ...but I already said extern... */
void doSomething(int y);
EXTERN_C_END
This happens because extern "C" int x;
is equivalent to extern "C" { extern int x; }
... not extern "C" { int x; }
. The latter form only gives "C linkage", but not the historical meaning of C extern. Then if you try to make the single-line form decay in C to extern, you can't say EXTERN_C extern int x;
, the compiler will complain in the C++ build at the two-externs-on-one-declaration.
Since there's no begin/end form, it's (often) going to mean more typing. But I prefer the "announcement of intent" to the compiler, even in the C case:
EXTERN_C int x;
EXTERN_C void doSomething(int y); /* does `extern` help the C case? */
I cannot offhand seem to create a good scenario where having the extern on the function declarations helps catch a mistake in C. But intuitively it seems there might be value in the redundancy, and as I say, having to do extern "C"
and then later still put extern
on things feels awkward.
What is the reasoning to prefer (or avoid) either approach?