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 haveextern "C"
when being interpreted as C -- hence the#ifdef __cplusplus
checking.
By declaring a function with extern "C" , it changes the linkage requirements so that the C++ compiler does not add the extra mangling information to the symbol. This pattern relies on the presence of the __cplusplus definition when using the C++ compiler. If you are using the C compiler, extern "C" is not used.
You need to use extern "C" in C++ when declaring a function that was implemented/compiled in C. Using extern "C" lets the compiler know that we want to use C naming and calling conventions. This causes the compiler to sort of entering C mode inside our C++ code.
“extern” keyword is used to extend the visibility of function or variable. By default the functions are visible throughout the program, there is no need to declare or define extern functions. It just increase the redundancy. Variables with “extern” keyword are only declared not defined.
The extern “C” keyword is used to make a function name in C++ have the C linkage. In this case the compiler does not mangle the function. Let us see what is the mangling in C++ first, then we can discuss about the extern “C” keyword. In C++ we can use the function overloading feature.
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
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.
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