extern "C", what is it useful for? [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Combining C++ and C - how does #ifdef __cplusplus work?
I come across the following lines in many libraries; what are they good for? When/where is __cplusplus defined?
#ifdef __cplusplus
extern "C" {
#endif
//...
#ifdef __cplusplus
}
#endif

__cplusplus is defined for C++ code. It happens sometimes that you have to mix C code, and C++ code. There can be many reasons for that, e.g. you have a driver written long ago in C that you want to use in your brand new C++0x project.
Every function type and name has a language linkage. There's a difference between C adn C++ functions, since C does not have function names overloading, a function name can serve as a unique identifier in C, but can not in C++. This is called function mangling.
Since you don't need to mangle the name in C, using extern "C" will make the compiler omit adding the parameter information for linkage.
The C++ standard explicitly states in 7.5 para 3:
Every implementation shall provide for linkage to functions written in
the C programming language, "C", and linkage to C++ functions, "C++".
complex sqrt(complex); //C++ linkage by default
extern "C" {
double sqrt(double);//C linkage
}

Related

Convert C libaries into C++ libs [duplicate]

This question already has answers here:
Using C Libraries for C++ Programs
(7 answers)
Closed 5 years ago.
I started with C recently.
I need to develop a TS3 Plugin, which is controlled over a tcp socket.
I would use a WebSocket.
I've found a bunch of libaries of Websockets but these are only for linux which uses pThread.h. And my TS3 Plugin will only run on Windows devices.
It is marked on the offical TS3 SDK Site that
Consisting of the ClientLib and the ServerLib, the TeamSpeak 3 SDK is
delivered as shared libraries with a C style coding interface to
provide developers direct access to the flexible and feature-rich set
of TeamSpeak 3's core functions using simple API calls.
With a standard C interface, the TeamSpeak SDK can be easily
integrated into high-level programming languages. No matter what
technology your application is using, the TeamSpeak SDK will fit in.
So that means that I could easly convert the ts3 api into C++ ?
The answer to your question, you don't need to convert the C libraries to C++. Basically, you can link the C library(Linux:.a/.so) or (Win:*.dll) and use that function into your corresponding modules.
Access C Code from Within C++ Source
In C++ language provides a "linkage specification" with which you declare that a function or object follows the program linkage conventions for a supported language.
The default linkage for objects and functions is C++. All C++ compilers also support C linkage, for some compatible C compiler.
When you need to access a function compiled with C linkage (for example, a function compiled by the C compiler, or a function written in assembler), declare the function to have C linkage.
Declaring Linkage Specifications
Use one of the following notations to declare that an object or function has the linkage of language language_name:
Example:
extern "C" void howdy(int);
extern "language_name" declaration ;
extern "language_name" { declaration ; declaration ; ... }
The first notation indicates that the declaration (or definition) that immediately follows has the linkage of language_name.
The second notation indicates that everything between the curly braces has the linkage of language_name, unless declared otherwise. Notice that you do not use a semicolon after the closing curly brace in the second notation.
You can nest linkage specifications, but the braces do not create scopes. Consider the following example:
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
}
All the functions above are in the same global scope, despite the nested linkage specifiers.
Including C Headers in C++ Code
If you want to use a C library with its own defining header that was intended for C compilers, you can include the header in extern "C" brackets:
extern "C" {
#include "header.h"
}
SIDENOTE: You need to to add this guard in your c header files in order to use that in C++.
#ifndef __YOURLIB_H_
#define __YOURLIB_H_
#ifdef __cplusplus
extern "C" {
#endif
int sample_func(int n);
#ifdef __cplusplus
}
#endif
#endif
Tutorial to use C lib in C++.

difference between extern "C" and simply extern [duplicate]

This question already has answers here:
What is the effect of extern "C" in C++?
(17 answers)
Closed 8 years ago.
I have seen C/C++ code using extern "C" declared in function signatures and also while including a C header into a CPP file.
but some functions just declare extern before their signature(without the "C").
QN1:
are these both ways of defining functions have same effect or do they imply different things?
sorry if I am very silly but I am not able to find this difference through Google.
Eg:
extern int someFunction( void *ret_val);
extern "C" int someFunction( void *ret_val);
QN2:
if a function is declared with an extern in its signature, is it necessary for the corresponding header file to be included inside a extern "C" block?
As pointed by another user in comments, the marked duplicate does not fully satisfy the question here. I am editing so that in future others may not be mislead into a different question.
extern "C" disables name mangling. It will allow your C++ code to call functions from library compiled by C compiler
extern "C" int someFunction( void *ret_val);
will make someFunction have C linkage.
The presence of extern "C" in a C++ file is a personal intent to disable name-mangling transformation that the C++ compiler does to the functions in that file. When there is no name-mangling, then a client C code can call these functions. This is done when you have a mixture of C/C++ code and you need to keep track of language-specific features. In a bit more geeky way, the C linkage becomes compatible in presence of a Cpp compiler.
The code could be anything from a variable/typedef to a full function/module declaration.
But if you do this:
extern char c; // same goes true for extern int foo()
it means that you are saying "I am using char c, which has a declaration external to this file". More like in another module somewhere in the search-path. This is implicitly global. In runtime, if c changes, the change is reflected everywhere. This is provided that your compiler directives such as -Iinclude_file_dirs -Ssource_file_dirs etc. are provided correctly (on GCC or g++). Using a powerful IDE such as Visual Studio 2010 or later, you can do these very easily.
"extern" is a linkage keyword. You can combine it with "C" for compiler-specific linkage directives.

extern "C"---when *exactly* to use? [duplicate]

This question already has answers here:
When to use extern "C" in simple words? [duplicate]
(7 answers)
Closed 9 years ago.
If you're tempted to flag this question as a duplicate, please note that I've read the questions on this subject, yet something still is unclear to me. I'm under the impression that this construct is used when including C headers and linking with C code (please do correct me if I'm wrong). Does it mean that I never have to use "extern C" when not dealing with object files? If I'm wrong about that, why can't the old C code just be compiled as C++, as most likely it's legal c++ code anyway?
I'm a bit iffy about it because I swear I've had situations when working with old C source code in C++ where a linker error is solved only with "extern C", and library headers do have
#ifdef __cplusplus
#extern "C"{
#endif
//......
#ifdef _cplusplus
}
#endif
around them.
EDIT: sorry for being unclear, but what I meant to ask is that whether it's true that "extern C" is only needed when including C headers and linking with pre-existing C object files? If it's true, (and it seems to be judging from comments below), why do library headers have "extern C" clauses around them, why can't they just be included and compiled as C++?
Name mangling rules are different for C. And C can have a different ABI than C++. These reasons alone require you to use extern "C" when embedding C code in C++ code. Even if a compiler can compile both C and C++ code, it might use different name mangling rules or ABIs for the two languages.
Also, your assertion that "[C code is] most likely ... legal c++ code" is not quite true, as C and C++ have diverged more and more as the years have gone on. They have a lot of similarities, but they also have a good number of differences.
The library itself is a C object file, therefore in order to use it your application has to expect a C-ABI for calling the functions in the library and you need to provide the appropriate hint to the compiler when you prototype the functions.
extern void libraryFunc();
If the library is actually compiled as C, which is the only way it can support C and C++, then you need to include annotation for C++ compilers that this MUST be linked as C.
#ifdef __cplusplus // only true when compiling with a C++ compiler
extern "C" {
#endif
extern void libraryFunc();
#ifdef __cplusplus
}
#endif
To a C compiler, this reads
extern void libraryFunc();
To a C++ compiler, this reads
extern "C" {
extern void libraryFunc();
...
}
which is equivalent to
extern "C" void libraryFunc();
If the duplication of extern bothers you, consider:
#if defined __cplusplus
# define C_EXTERN extern "C"
#else
# define C_EXTERN extern
#endif
EXTERN_C {
void foo();
}
The compiler and linker now know to use the C ABI when trying to call/link that function.
Note that the C++ ABI is a superset of the C ABI (application binary interface) so if you want to share code, C is the LCD and needs to be your common interface. C is completely unaware of C++ "name mangling" etc.
This is essentially answered here: When to use extern "C" in simple words?
But the pertinent point is that, when compiling in C++, the names of functions are "mangled" to encode certain information about the function (like argument types). Since C++ always mangles a function name the same way, everything is consistent between the mangled name call and what is put in the object file.
If you compile a file in C called "foo", and in your C++ file you have extern foo(int c);, the C++ compile will have mangled "foo" into something different, for example, foo__Ic (I just made it up, the actual mangling will look different).
Meanwhile, in the plain C code compiled with the C compiler, the object code has defined symbol that is simply foo.
However, when the whole thing is linked, the C++ code has an external symbol foo__Ic that it's trying to resolve, which does not match the defined symbol foo in the C object file.
Hope that helps.
There's another case not mentioned yet. extern "C" specifies the C linkage, but C is not the only other language. C linkage is also used by other languages which are too obscure to have their own widely accepted linkage. E.g. Java uses C linkage, too. Obviously you can't compile that Java code with C++, so you do need extern "C" on the C++ side.

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

This question already has answers here:
What is the effect of extern "C" in C++?
(17 answers)
Closed 8 years ago.
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?
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.
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++.
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.
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.
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
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++.
C++ functions are subject to name mangling. This makes them impossible to call directly from C code unless extern "C" is used.

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?
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.
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.
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
}
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.
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:
C and C++ use different name mangling rules. Essentially, extern "C" tells the C++ compiler to name the function as C would name it.
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.
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.
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++" { ... }.
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.
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.