Question

Why shouldn’t extern "C" be specified for a function that needs to be defined as a C function? What effect would that have on the compiler when compiling the file as a C source?

If there is no effect on the C compiler, can’t we just define a function in a header file as below by removing the #ifdef __cplusplus check?

extern "C" {
    int MyFunc();
}

An answer to another question says that the #ifdef is needed, but I don’t understand why:

Regarding #2: __cplusplus will be defined for any compilation unit that is being run through the C++ compiler. Generally, that means .cpp files and any files being included by that .cpp file. The same .h (or .hh or .hpp or what-have-you) could be interpreted as C or C++ at different times, if different compilation units include them. If you want the prototypes in the .h file to refer to C symbol names, then they must have extern "C" when being interpreted as C++, and they should not have extern "C" when being interpreted as C -- hence the #ifdef __cplusplus checking.

Was it helpful?

Solution

The construct extern "C" is a C++ construct and is not recognized by a C compiler. Typically, it will issue a syntax error message.

A common trick is to define a macro, for example EXTERN_C, that would expand to different thing depending on if you compile using C or C++. For example:

In a common header file:

#ifdef __cplusplus
#define EXTERN_C extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C
#define EXTERN_C_END
#endif

In other files:

EXTERN_C
int MyFunc(void);
EXTERN_C_END

OTHER TIPS

If you compile a source file as C, it will not recognize extern "C", and would usually result in a compilation error.

If you compile a source file as C++, it will recognize extern "C", and the correct names will be linked.

Therefore, you can only use it reliably to specify C symbol names for files you compile as C++.

If you compile sources as C and C++, or your interfaces are intended for C and C++ clients, you would need to specify this one way or another in order for your clients to get the correct symbols when linking (and so on).

Related: You are allowed to write extern "C++" - for C++ translations.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top