How does extern "C" work in C++? [duplicate] - c++

This question already has answers here:
What is the effect of extern "C" in C++?
(17 answers)
Closed 6 years ago.
I see some code in C++ using extern "C" at the beginning of the file like this:
#ifdef __cplusplus
extern "C" {}
#endif
What does this mean? How does it work?

It is used to inform the compiler to disable C++ name mangling for the functions defined within the braces. http://en.wikipedia.org/wiki/Name_mangling

It's probably not like that, but more like:
#ifdef __cplusplus
extern "C" {
#endif
//some includes or declarations
#ifdef __cplusplus
}
#endif
It tells the compiler to use C name mangling for whatever is declared inside the directives.
The way you have it now:
#ifdef __cplusplus
extern "C" {}
#endif
is just dead code.

Extern "C" - notify the compiler,that the noted function is compiled in C style.

It specifies a linkage specification.
It tells the linker how to link the code.
It is useful when you want to mix C and C++ code.

Related

How to detect if C code (which needs 'extern C') is compiled in C++

I have a C header as part of a C++ library.
This C header would only make sense compiled by a C compiler, or by a C++ compiler within an extern "C" { ... } block, otherwise unresolved link errors would happen.
I thought to add a block such as:
#ifdef __cplusplus
#error "Compiling C bindings with C++ (forgot 'extern \"C\"'?)"
#endif
in the C header, but unfortunately the __cplusplus macro is defined also within an extern "C" { ... } block.
Is there another way to detect this condition correctly?
The common practice is not to demand client code wraps your header in extern "C", but to do so conditionally yourself. For instance:
#ifdef __cplusplus
extern "C" {
#endif
// Header content
#ifdef __cplusplus
}
#endif
That way client code is automatically correct without doing anything beyond including the header.

C/C++ extern "C" Variable compilation Macro

How do I test to see if I am linking in C++ or C using macros?
Say I have code that should link as C in a C++ file, I would use extern "C"{//code here}which would make my code in a link as C . How would I set up my name.c file to work for both C and C++. Something like...
#ifdef C++//or other macro
extern "C"{
#endif
#ifdef C++
}
#endif
What is the proper macro to replace the "C++" I have above, and will it be cross platform? or how can I set it up to be cross platform?
Also, What is the significance of having to do the extern "C"{} for C code in a C++ file?
Any help is appreciated. Thanks in advance.
"What is the proper macro to replace the "C++""
It's #ifdef __cplusplus
#ifdef __cplusplus
extern "C"{
#endif
//.....
#ifdef __cplusplus
}
#endif
For "...What is the significance of having to do....?"
Read : In C++ source, what is the effect of extern ā€œCā€?

When should you wrap include in `extern "C"` when including a C Library

I understand that when you include a c header in your c++ project you must wrap it with extern "C" because c++ and c have two different ways of identifying function. c will use the name to identify a function and c++ must use the name and the parameters to satisfy function overloading.
What I don't understand is why are there are c headers that don't require to be wrapped in extern "C" like windows.h??
In general, wrapping a C header in extern "C" is not a good idea. The header might include other files that break when you do this. A C header that is designed to be used in C++ will handle extern "C" appropriately, without you having to do anything. Typical code:
#ifndef MY_HEADER_INCLUDE_GUARD
#define MY_HEADER_INCLUDE_GUARD
#ifdef __cplusplus
extern "C" {
#endif
/* C callable stuff goes here */
#ifdef __cplusplus
}
#endif
#endif /* MY_HEADER_INCLUDE_GUARD */

C linkage and c++ headers

I want to use some c++ classes in shared library with C linkage. And i got following problems.
If
#include <iostream>
extern "C"
{
void f(){}
}
Compiles and links succesfully, but f() could not be found in resulting library.
If
extern "C"
{
#include <iostream>
void f(){}
}
I got many compiler errors (just dont know how to correctly translate them in english, something about template with C linkage) on every occurence of C++ keyword "template" in iostream and included headers.
What should be done?
The first variant is correct. Only stuff that even exists in C can be declared in a extern "C" block, and templates and classes certainly don't belong in that category. You only have to make sure, that your function is also declared as extern "C" in the header if you are using a C++-compiler. This is often achieved by writing
#ifdef __cplusplus
// C++ declarations (for example classes or functions that have C++ objects
// as parameters)
extern "C"
{
#endif
// C declarations (for example your function f)
#ifdef __cplusplus
}
#endif
in the header.
The first is correct; system headers (and most other headers as well)
can only be included at global scope, outside any namespaces, classes,
functions or linkage specification blocks. There are likely things in
<iostream> that wouldn't be legal in an extern "C", and even if
there weren't, the name mangling for extern "C" is almost certainly
different from that of C++, and the library itself was surely compiled
as extern "C++".
How did you define f? This could be a similar problem: if the source
file compiles it as an extern "C++" function, then the name will be
mangled differently than it was in the client files which compiled it as
an extern "C" function.
The general policy here is to handle the headers and the function
definitions/declarations in the same way you normally do, except that
you ensure that the header can be included in both C and C++ sources,
e.g.:
#if __cplusplus
extern "C" {
#endif
void f();
// Other `extern "C"` functions...
#if __cplusplus
}
#endif
Then include this header in all files where the function f() is used,
and in the file where it is defined.
Use __declspec to export functions, classes, etc...
Also: http://msdn.microsoft.com/en-us/library/a90k134d(v=vs.80).aspx
And this one is very good: http://www.flounder.com/ultimateheaderfile.htm

Does extern "C" have any effect in C?

I just got some C code that uses extern "C" to declare external functions like this:
extern "C" void func();
Is this valid C? I'm getting an error at this line, but I'm not sure if it's because of this or something else.
No, it's not valid C. It should only be used in C++ code to refer to functions defined in C code. The extern "C" should be surrounded in a ifdef __cplusplus/#endif block:
// For one function
#ifdef __cplusplus
extern "C"
#endif
void func();
// For more than one function
#ifdef __cplusplus
extern "C"
{
#endif
void func1();
void func2();
#ifdef __cplusplus
}
#endif
this is a C++ notation to tell the compiler/linker to use C calling standards.
Usually that line is wrapped in an pre-processor statement.
#ifdef __cplusplus
extern "C" {
#endif
// stuff
#ifdef __cplusplus
}
#endif
Not valid in C. If present after preprocessing this will result in a diagnostic as per the standard.
For C++, this turns of name-mangling. See this for more details as to why it may be required. Can you post some more details?