tags:

views:

1278

answers:

5
+5  Q: 

extern "C"

Hello, Stack Overflow!

I was wondering what exactly putting 'extern "C"' in your C++ program does.

Thanks!

+1  A: 

It informs the C++ compiler to look up the names of those functions in a C-style when linking, because the names of functions compiled in C and C++ are different during the linking stage.

Mark Rushakoff
+2  A: 

It changes the linkage of a function in such a way that the function is callable from C. In practice that means that the function name is not mangled.

Employed Russian
mangled or decorated what is the proper term?
ojblass
Mangled is the term generally used... Don't believe I've ever seen 'decorated' used with this meaning.
Matthew Scharley
People use "mangling" when they mean the radical encoding of types and expressions for overloading into names. And "decorating" when they mean little things like prepending an underscore or "@" or something similar. But i believe the terms are not clearly defined. I use both interchangeable.
Johannes Schaub - litb
+23  A: 

extern "C" makes a function-name in C++ have 'C' linkage (compiler does not mangle the name) so that client C code can link to (i.e use) your function using a 'C' compatible header file that contains just the declaration of your function. Your function definition is contained in a binary format (that was compiled by your C++ compiler) that the client 'C' linker will then link to using the 'C' name.

Since C++ has overloading of function names and C does not, the C++ compiler cannot just use the function name as a unique id to link to, so it mangles the name by adding information about the arguments. A C compiler does not need to mangle the name since you can not overload function names in C. When you state that a function has extern "C" linkage in C++, the C++ compiler does not add argument/parameter type information to the name used for linkage.

Just so you know, you can specify "C" linkage to each individual declaration/definition explicitly or use a block to group a sequence of declarations/definitions to have a certain linkage:

extern "C" void foo(int);
extern "C"
{
   void g(char);
   int i;
}

If you care about the technicalities, they are listed in section 7.5 of the C++03 standard, here is a brief summary (with emphasis on extern "C"):

  • extern "C" is a linkage-specification
  • Every compiler is required to provide "C" linkage
  • a linkage specification shall occur only in namespace scope
  • all function types, function names and variable names have a language linkage
  • two function types with distinct language linkages are distinct types even if otherwise identical
  • linkage specs nest, inner one determines the final linkage
  • extern "C" is ignored for class members
  • at most one function with a particular name can have "C" linkage (regardless of namespace)
  • extern "C" forces a function to have external linkage (cannot make it static)
  • Linkage from C++ to objects defined in other languages and to objects defined in C++ from other languages is implementation-defined and language-dependent. Only where the object layout strategies of two language implementations are similar enough can such linkage be achieved
Faisal Vali
+1 for c++'s name mangling
arsane
This appears to be under-the-hood ... is there any functional reason why I would put 'extern "C"' in front of a function (other than to call it from a separate C program)?
Litherum
C compiler does not use mangling which c++'s does. So if you want call a c interface from a c++ program, you have to clearly declared that the c interface as "extern c".
arsane
@Litherum - if you do not intend your code to be linked-to by a different C++ compiler or any C compiler or some dynamic language (ruby, python etc) for which you are developing an extension - you don't need extern "C". It buys you nothing.
Faisal Vali
@Faisal: do not try to link code built with different C++ compilers, even if the cross-references are all 'extern "C"'. There are often differences between the layouts of classes, or the mechanisms used to handle exceptions, or the mechanisms used to ensure variables are initialized before use, or other such differences, plus you might need two separate C++ run-time support libraries (one for each compiler).
Jonathan Leffler
@Leffler - thanks, you make good points. I did not mean to encourage using different C++ compilers by using extern "C". Rather, I was hoping to suggest that if you are not writing something that would need to be linked to by another C++ compiler, you probably don't need extern "C".
Faisal Vali
+1 Nice answer :)
Magnus Skog
+5  A: 

I'd like to introduce you this article:

http://www.agner.org/optimize/calling_conventions.pdf

It tells you much more about calling convention and the difference between different compiler.

arsane
+1 Nice reference :)
Faisal Vali
+1 Excellent reference!
Jonathan Leffler
A: 

In every C++ program, all non-static functions are represented in the binary file as symbols. These symbols are special text strings that uniquely identify a function in the program.

In C, the symbol name is the same as the function name. This is possible because in C no two non-static functions can have the same name.

Because C++ allows overloading and has many features that C does not — like classes, member functions, exception specifications - it is not possible to simply use the function name as the symbol name. To solve that, C++ uses so-called name mangling, which transforms the function name and all the necessary information (like the number and size of the arguments) into some weird-looking string which only the compiler knows about.

So if you specify a function to be extern C, the compiler doesn't performs name mangling with it and it can be directly accessed using its symbol name.

This comes handy while using dlsym() and dlopen() for calling such functions.

Neeraj