I know how to use extern "C"
but what are the conditions when you have to use it?
extern "C"
tells the C++ compiler not to perform any name-mangling on the code within the braces. This allows you to call C functions from within C++.
For example:
#include <string.h>
int main()
{
char s[] = "Hello";
char d[6];
strcpy_s(d, s);
}
While this compiles fine on VC++. But sometimes this is written as:
extern "C" {
#include <string.h>
}
I don't see the point. Can you give a real example where extern "C"
is necessary?
You use extern "C"
to prevent name mangling inside header files and your C++ object files for libraries or objects that have already been compiled without mangling.
For example, say you have a widget
library which was compiled with a C compiler so that its published interface is non-mangled.
If you include the header file as is into your code, it will assume the names are mangled and those mangled versions are what you'll tell the linker to look for.
However, since you'll be asking for something like function@intarray_float_charptr
and the widget
library will have only published function
, you're going to run into problems.
However, if you include it with:
extern "C" {
#include "widget.h"
}
your compiler will know that it should try to use function
, the non-mangled version.
That's why, in header files for C stuff meant to be included in C _or C++ programs, you'll see things like:
#ifdef __cplusplus
extern "C" {
#endif
// Everything here works for both C and C++ compilers.
#ifdef __cplusplus
}
#endif
If you use a C compiler to include this, the #ifdef
lines will cause the extern "C"
stuff to disappear. For a C++ compiler (where __cplusplus
is defined), everything will be non-mangled.
One very common use of extern "C"
when you are exporting a function from a library. If you don't disable C++ name mangling you can otherwise make it very hard for clients of your library to name your function. And likewise, when going in the other direction, when you are importing a function that has been exported with C linkage.
Here is a concrete example of where things break and need extern "C"
to get fixed.
module.h
:
int f(int arg);
module.c
:
int f(int arg) {
return arg + 1;
}
main.cpp
:
#include "module.h"
int main() {
f(42);
}
Since I am mixing C and C++, this won't link (of the two object files, only one will know f
under its C++ mangled name).
Perhaps the cleanest way to fix this is by making the header file compatible with both C and C++:
module.h
:
#ifdef __cplusplus
extern "C" {
#endif
int f(int arg);
#ifdef __cplusplus
}
#endif
When you link with libraries that are written in C extern
tells the compiler not to decorate the names so that the linker can find the functions. In C++ function names et al have information for the linker e.g. argument types and sizes contained in the name.
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