Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use extern "C"?

Tags:

c++

extern-c

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?

like image 541
user103214 Avatar asked Nov 03 '11 14:11

user103214


4 Answers

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.

like image 81
paxdiablo Avatar answered Nov 08 '22 13:11

paxdiablo


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.

like image 45
David Heffernan Avatar answered Nov 08 '22 15:11

David Heffernan


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
like image 36
NPE Avatar answered Nov 08 '22 14:11

NPE


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.

like image 36
AndersK Avatar answered Nov 08 '22 15:11

AndersK