tags:

views:

314

answers:

8

Hello,

Maybe I'm not understanding the differences between C and C++, but when and why do we need to use:

extern "C" {

? Apparently its a "linkage convention"?

I read about it briefly and noticed that all the .h header files included with MSVS surround their code with it. What type of code exactly is "C code" and NOT "C++ code"? I thought C++ included all C code?

I'm guessing that this is not the case and that C++ is different and that standard features/functions exist in one or the other but not both (ie: printf is C and cout is C++), but that C++ is backwards compatible though the extern "C" declaration. Is this correct?

My next question depends on the answer to the first, but I'll ask it here anyway: Since MSVS header files that are written in C are surrounded by extern "C" { ... }, when would you ever need to use this yourself in your own code? If your code is C code and you are trying to compile it in a C++ compiler, shouldn't it work without problem because all the standard h files you include will already have the extern "C" thing in them with the C++ compiler?

Do you have to use this when compiling in C++ but linking to alteady built C libraries or something?

Please help clarify this for me... Thanks!

--Keith

A: 

C++ functions are subject to name mangling. This makes them impossible to call directly from C code unless extern "C" is used.

George Edison
+6  A: 

C++ compilers mangle the names in their symbol table differently than C compilers. You need to use the extern "C" declaration to tell the C++ compiler to use the C mangling convention instead when building the symbol table.

Ignacio Vazquez-Abrams
A: 

See C++ FAQ lite

A good place to start.

Lazer
+9  A: 

You need to use extern "C" in C++ when declaring a function that was implemented/compiled in C. The use of extern "C" tells the compiler/linker to use the C naming and calling conventions, instead of the C++ name mangling and C++ calling conventions that would be used otherwise. For functions provided by other libraries, you will almost never need to use extern "C", as well-written libraries will already have this in there for the public APIs that it exports to both C and C++. If, however, you write a library that you want to make available both in C and in C++, then you will have to conditionally put that in your headers.

As for whether all C code is C++ code... no, that is not correct. It is a popular myth that C++ is a "superset of C". While C++ certainly strives to be as compatible with C as possible, there are some incompatibilities. For example, bool is valid C++ but not valid C, while _Bool exists in C99, but is not available in C++.

As to whether you will ever need to use extern "C" with the system's ".h" files.... any well-designed implementation will have those in there for you, so that you do not need to use them. However, to be certain that they are provided, you should include the equivalent header file that begins with "c" and omits ".h". For example, if you include <ctype.h>, almost any reasonable system will have the extern "C" added; however, to be assured a C++-compatible header, you should instead include the header <cctype>.

You may also be interested in Mixing C and C++ from the C++ FAQ Lite.

Michael Aaron Safyan
Thanks for responses all. So do I only need to use this when including code that has already been compiled in a C compiler?
Russel
@Russel, yes, assuming that you are including it from C++, and assuming that the header does not already use extern "C".
Michael Aaron Safyan
I think it's a nice answer!
Johannes Schaub - litb
Thanks for the response! Thanks everyone, makes sense to me now.
Russel
+1  A: 

I use 'extern c' so that C# can read my C++ code without having to figure out the extra name mangling done when exporting a C++ dll function. Otherwise, there are extra nonsensical (or really, non-English) characters that I have to add at the end of a function entry point on the C# side in order to properly access a C++ function in a dll.

mmr
+1  A: 

extern "C" {} blocks tell a C++ compiler to use the C naming and calling conventions. If you don't use this you will get linker errors if trying to include a C library with your C++ project because C++ will mangle the names. I tend to use this on all my C headers just in case they are ever used in a C++ project:

#ifdef __cplusplus
extern "C" {
#endif

/* My library header */

#ifdef __cplusplus
} // extern
#endif
Mike Weller
+1  A: 

You need to use extern "C" when you want to use the C calling convention in code compiled by a C++ compiler. There are two reasons for this:

  • You have a function implemented in C and want to call it from C++.

  • You have a function implemented in C++ and want to call it from C. Note that in this case you can only use the C part of C++ in the function interface (no classes, ...).

Apart from C this also applies when you want to interoperate between C++ and other languages which use the same calling and naming conventions as C.

Typically the declarations in a C header file are surrounded with

#ifdef __cplusplus
extern "C" {
#endif

[... C declarations ...]

#ifdef __cplusplus
}
#endif

to make it usable from C++.

starblue
+1  A: 

The other answers are correct, but a complete "boilerplate" example will probably help. The canonical method for including C code in C and/or C++ projects is as follows:

//
// C_library.h
//

#ifdef __cplusplus
extern "C" {
#endif

//
// ... prototypes for C_library go here ...
//

#ifdef __cplusplus
}
#endif

-

//
// C_library.c
//

#include "C_library.h"

//
// ... implementations for C_library go here ...
//

-

//
// C++_code.cpp
//

#include "C_library.h"
#include "C++_code.h"

//
// ... C++_code implementation here may call C functions in C_library.c ...
//

-

Paul R
Great example, thank you.I've read about calling conventions for C++.. (_cdecl, _stdcall, _fastcall, etc). Is there only one calling convention for C??
Russel
@Russel: _cdecl, _stdcall, _fastcall, etc are all non-standard Windows-specific abominations which are not found in the civilised world. ;-)
Paul R
I apologize :) Can anyone point me to better documentation on calling conventions than MSDN? Also, does C only have one standard calling convention?
Russel
Yes, standard C really only has one calling convention, but there are various non-standard extensions that you may run into in addition to the aforementioned Microsoft abominations, such as `far` and `pascal`, to name two.
Paul R