It should enclose the declarations in the header file, and definitions should be enclosed as long the translation unit is compiled using the c++ compiler, and as long the declaration wasn't seen there.
It's never wrong doing both in c++ code.
If the c compiler is used to compile the function definitions, it's not necessary (or should I better to say would be wrong syntax, see the note below).
extern "C" {}
scopes control that plain c symbols linkage is used for everything inside. Otherwise c++ name mangling would be applied.
Note:
Since extern "C" {}
this isn't valid c syntax, to make that working with the c compiler, you'll need to use it within #ifdef
:
MyHeader.h
:
#ifdef __cplusplus
extern "C" {
#endif
// ... c style function name declarations
void foo(int i);
#ifdef __cplusplus
} // extern "C"
#endif
The use of the extern "C" {}
scope is actually twofold:
Exporting C++ code to C
If the above is compiled with the c compiler, it appears for it as a normal c function declaration. If compiled with the c++ compiler the extern
keyword applies and the c++ name mangling will be suppressed.
Regarding the definition, the function can use any c++ features inside it's definition:
extern "C" {
void foo(int x) {
std::vector v(x);
// ... blah, more c++ stuff
}
}
Note that the declaration wasn't included here. This can be used as a technique, particularly useful when you want to override functions exposed from a library for weak linkage.
In case of including the MyHeader.h
, the extern "C" {}
scope can be omitted.
Importing C code from C++
If the above declaration is seen in the c++ compiler, again c++ name mangling is suppressed, and any call reference to foo()
wil be resolved by the linker using a plain c function symbol name:
#include "MyHeader.h"
class MyClass {
public:
void bar(int y) {
// Use foo() as plain c function:
foo(y);
}
};
The foo()
function implementation is provided from an object file (or archive) that was created using the c compiler.