Why would you use 'extern "C++"'?

In this article the keyword extern can be followed by "C" or "C++". Why would you use 'extern "C++"'? Is it practical?

36371 次浏览

The language permits:

extern "C" {
#include "foo.h"
}

What if foo.h contains something which requires C++ linkage?

    void f_plain(const char *);
extern "C++" void f_fancy(const std::string &);

That's how you keep the linker happy.

Short answer is that you can use extern C to tell the compiler not to use name-mangling. This means you can link together bits of C and C++ code in the same project.

C and C++ use different name mangling rules. Essentially, extern "C" tells the C++ compiler to name the function as C would name it.

extern "C" is used to say that a C++ function should have C linkage. What this means is implementation dependant, but normally it turns off C++ name-mangling (and so overloading and strict type checking). You use it when you have a C++ function you want to be called from C code:

extern "C" void Foo();   // can be called easily from C

As for extern "C++", I've never seen it in real code, though the C++ Standard allows it. I guess it is a no-op.

There is no real reason to use extern "C++". It merely make explicit the linkage that is the implicit default. If you have a class where some members have extern "C" linkage, you may wish the explicit state that the others are extern "C++".

Note that the C++ Standard defines syntactically extern "anystring". It only give formal meanings to extern "C" and extern "C++". A compiler vendor is free to define extern "Pascal" or even extern "COM+" if they like.

This specify which link convention to use. Most languages know how to link with a "C" style function.

You need this in two cases :

  • A C - or other languages for that matter- program calling a function written in C++
  • A C++ program calling a function written in C

Example :

// declared in function.h
void f1(void);

Your C code - actually other languages are able to link with C function - will not be able to link to it because the name in the object table will use C++ convention.

If you write

extern "C" void f1(void);

Now the linking works because it uses C convention.

Two guesses:

  • If you are in a extern "C" block, you can get C++ language linkage again by specifying a nested extern "C++".
  • It reserves C++ linkage, because it's the document defining C++. Who is in a better position for defining C++ language linkage than it itself. It also provides for completeness. Same deal as with signed/unsigned.

Read this answer that explains extern "LanguageName" (i.e GCC has extern "Java") aswell.

The #1 reason I use extern "C" is to avoid C++'s name mangling rules. This is very important if you are working in a .Net language and want to PInvoke into a particular native function. The only way to do this is with name mangling disabled.

I'm not sure why you would need to do it, but according to this article from Sun, you can use extern "C++" inside a block of extern "C" to specify certain functions in a group of "C" functions have the native C++ linkage.

extern "C" {
void f();             // C linkage
extern "C++" {
void g();         // C++ linkage
extern "C" void h(); // C linkage
void g2();        // C++ linkage
}
extern "C++" void k();// C++ linkage
void m();             // C linkage
}

Extern "C" is answered by many. The use case for extern "C++" is when calling C++ library function in a C function. The sub-use case, that is relevant, is when linking a C++ library with a C source code with main function. Check this wiki page for more details:

To answer the second question, "is it practical?":

It is practical, and practically unavoidable, in standard headers like <cmath>.

Imagine a header-only library X.h, written in a common subset of C++ and C, and intended to be used from both languages. For the benefit of C++ users, X.h includes <cmath>, not <math.h>. This would not work for C users though, hadn't the authors of <cmath> sandwiched everything in extern "C++" { ... }.