When to use extern "C" in simple words? [duplicate]
Asked Answered
E

7

38

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 already built C libraries or something?

Exanthema answered 9/5, 2010 at 6:11 Comment(3)
C++ is NOT a superset of C. There is valid C which is not valid C++.Rockbottom
theatrus is right: #2744072Utoaztecan
@YannRamin you should link some useful stuff to validate your argument.Compensatory
H
41

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.

Hecatomb answered 9/5, 2010 at 6:14 Comment(3)
Thanks for responses all. So do I only need to use this when including code that has already been compiled in a C compiler?Exanthema
@Russel, yes, assuming that you are including it from C++, and assuming that the header does not already use extern "C".Hecatomb
Ah, so that's why calling a C function in C++ gives linkage and symbol errors ...Atal
F
28

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 ...
//

Note: the above also applies to calling C code from Objective-C++.

Felicity answered 9/5, 2010 at 6:58 Comment(4)
Great example, thank you. I've read about calling conventions for C++.. (_cdecl, _stdcall, _fastcall, etc). Is there only one calling convention for C??Exanthema
@Russel: _cdecl, _stdcall, _fastcall, etc are all non-standard Windows-specific abominations which are not found in the civilised world. ;-)Felicity
I apologize :) Can anyone point me to better documentation on calling conventions than MSDN? Also, does C only have one standard calling convention?Exanthema
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.Felicity
O
18

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.

Oliy answered 9/5, 2010 at 6:13 Comment(0)
D
3

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.

Desist answered 9/5, 2010 at 6:24 Comment(0)
C
3

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
Chambertin answered 9/5, 2010 at 6:25 Comment(0)
J
3

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++.

Joleen answered 9/5, 2010 at 6:37 Comment(0)
S
1

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

Selfliquidating answered 9/5, 2010 at 6:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.