extern-c
Is there a side effect in doing this:
C code:
struct foo {
int k;
};
int ret_foo(const struct foo* f){
return f.k;
}
C++ code:
class bar : public foo {
int my_bar() {
return ret_foo( (foo)this );
}
};
There's an extern "C"
around the C++ code and each code is inside its own compilation unit.
Is this portable across compilers?
Could we use extern "C" in C file without #ifdef __cplusplus?Why shouldn’t extern "C"
be specified for a function that needs to be defined as a C function? What effect would that have on the compiler when compiling the file as a C source?
If there is no effect on the C compiler, can’t we just define a function in a header file as below by removing the #ifdef __cplusplus
check?
extern "C" {
int MyFunc();
}
An answer to another question says that the #ifdef
is needed, but I don’t understand why:
Why do you need "extern C" for C++ callbacks to C functions?Regarding #2: __cplusplus will be defined for any compilation unit that is being run through the C++ compiler. Generally, that means .cpp files and any files being included by that .cpp file. The same .h (or .hh or .hpp or what-have-you) could be interpreted as C or C++ at different times, if different compilation units include them. If you want the prototypes in the .h file to refer to C symbol names, then they must have
extern "C"
when being interpreted as C++, and they should not haveextern "C"
when being interpreted as C -- hence the#ifdef __cplusplus
checking.
I find such examples in Boost code.
namespace boost {
namespace {
extern "C" void *thread_proxy(void *f)
{
....
}
} // anonymous
void thread::thread_start(...)
{
...
pthread_create(something,0,&thread_proxy,something_else);
...
}
} // boost
Why do you actually need this extern "C"
?
It is clear that the thread_proxy
function is private internal and I do not expect that it
would be mangled as "thread_proxy" because I actually do not need it mangled at all.
In fact, in all my code that I had written and that runs on many platforms, I never used extern "C"
and this had worked as-is with normal functions.
Why is extern "C"
added?
My problem is that extern "C"
functions pollute the global namespace and they are not actually hidden as the author expects.
This is not a duplicate! I'm not talking about mangling and external linkage. It is obvious in this code that external linkage is unwanted!
Answer: The calling conventions of C and C++ functions are not necessarily the same, so you need to create one with the C calling convention. See 7.5 (p4) of C++ standard.
extern and extern "C" for variablesI'm writing a C++ shared library for a C program to use. However, I have a question about extern
and extern "C"
.
Consider the following code
My header file is like this:
#ifdef __cplusplus
extern "C" int global;
extern "C" int addnumbers(int a, int b);
#else
extern int global;
#endif
This works perfectly fine; I just have to declare
int global;
in either my .cpp or my .c file. However, what I don't understand is:
What is the difference between extern "C"
and extern
here? I tried commenting out extern "C" int global
and it works! Why?
I know that extern "C"
is used for making C linkage. That's why I have extern "C" int addnumbers(int,int)
. In other words, if I want to write a C++ function that is to be used in a C program, I write extern "C"
. Now, what about global variables - the situation is different here I guess? I want the C program to use a C++ variable named global
, but I can use extern
not extern "C"
. Why is that? This is not intuitive to me.
Comment: I don't think this is a duplicate, because I'm asking what the difference is when you use it for variables versus functions.
Call a C function from C++ codeI have a C function that I would like to call from C++. I couldn't use "extern "C" void foo()
" kind of approach because the C function failed to be compiled using g++. But it compiles fine using gcc. Any ideas how to call the function from C++?
I'm writing a C library, which may potentially be useful to people writing C++. It has a header which looks like this:
#ifndef FOO_H_
#define FOO_H_
#include <bar.h>
#include <stdarg.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
void foo_func();
#ifdef __cplusplus
}
#endif
#endif
and I was wondering - should I move the extern "C"
bit before including the header include directives? Especially seeing how, in practice, some of those headers might themselves have an extern "C"
?
I know this.
Calling C function from C++:
If my application was in C++ and I had to call functions from a library written in C. Then I would have used
//main.cpp
extern "C" void C_library_function(int x, int y);//prototype
C_library_function(2,4);// directly using it.
This wouldn't mangle the name C_library_function
and linker would find the same name in its input *.lib files and problem is solved.
Calling C++ function from C???
But here I'm extending a large application which is written in C and I need to use a library which is written in C++. Name mangling of C++ is causing trouble here. Linker is complaining about the unresolved symbols. Well I cannot use C++ compiler over my C project because thats breaking lot of other stuff. What is the way out?
By the way I'm using MSVC
When to use extern "C" in simple words?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?
"C linkage function cannot return C++ class" in Visual Studio 2019I have the following function:
class Foo;
template <typename T>
struct PyArray1D{
std::size_t size;
T *array;
};
extern "C" PyArray1D<Foo> SimulatePhotonEvents()
{
Foo * foo = new Foo();
return {1, foo}
}
However this does not compile using VS2019 (however it does with gcc) with the warning
C linkage function cannot return C++ class
However it does work when the template argument is a double for example... I can return a 'PyArray1D', without VS complaining.
So I added a new struct:
struct FooArray {
std::size_t size;
Foo *data;
};
And return this from the extern C function.
extern "C" FooArray SimulatePhotonEvents()
{
Foo * foo = new Foo();
return {1, foo}
}
And to my big surprise this worked! My question is, why?
Isn't VS smart enough to see that the FooArray get's created out of the template function? And are there other, less hacky ways to solve this?
When to use extern "C" in C++?Possible Duplicate:
Why do we need extern “C”{ #include <foo.h> } in C++?
I have often seen programs coded like:
extern "C" bool doSomeWork() {
//
return true;
}
Why do we use an extern "C"
block? Can we replace this with something in C++? Is there any advantage to using extern "C"
?
I do see a link explaining this but why do we need to compile something in C when we already have C++?
What kinds of C++ functions can be placed in a C function pointer?I have a C library that uses a struct of function pointers for callbacks. The callbacks will be called from C code.
extern "C" {
typedef struct callbacks_t {
void (*foo) (const char*);
int (*bar) (int);
} callbacks_t;
}// extern C
What kinds of C++ functions can I safely place in those function pointers to be called from the C library? Static member functions? Fully specified template functions? Non-capturing Lambdas?
g++ seemingly lets me use all of the above, but I question the safety when different calling conventions and language bindings are used for C and C++ functions.
Why do we need extern "C"{ #include <foo.h> } in C++?Why do we need to use:
extern "C" {
#include <foo.h>
}
Specifically:
When should we use it?
What is happening at the compiler/linker level that requires us to use it?
How in terms of compilation/linking does this solve the problems which require us to use it?
I had an interview recently and one question asked was what is the use of extern "C"
in C++ code. I replied that it is to use C functions in C++ code as C doesn't use name-mangling. I was asked why C doesn't use name-mangling and to be honest I couldn't answer.
I understand that when the C++ compiler compiles functions, it gives a special name to the function mainly because we can have overloaded functions of the same name in C++ which must be resolved at compile time. In C, the name of the function will stay the same, or maybe with an _ before it.
My query is: what's wrong with allowing the C++ compiler to mangle C functions also? I would have assumed that it doesn't matter what names the compiler gives to them. We call functions in the same way in C and C++.
How does extern "C" work in C++?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?
difference between extern "C" and simply externI 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 return class objectI want to have a plugin, with a simpler name to resolve in other C++ code.
class B {
};
extern "C" B foo(); // to avoid name mangling in order to be loaded by dlsym
And in the other part of the program (which is also in C++ and shares the same definition of class B with the plugin):
B (*func)();
func = dlsym("/path/to/so", "foo");
B m = func();
Will such code cause any problem, i.e. is it allowed (by standard) to use a C++ class as parameter or return type in an extern "C"
function? It seems to work on my gcc, but what about the others?
I'm working on a project that has a lot of legacy C code. We've started writing in C++, with the intent to eventually convert the legacy code, as well. I'm a little confused about how the C and C++ interact. I understand that by wrapping the C code with extern "C"
the C++ compiler will not mangle the C code's names, but I'm not entirely sure how to implement this.
So, at the top of each C header file (after the include guards), we have
#ifdef __cplusplus
extern "C" {
#endif
and at the bottom, we write
#ifdef __cplusplus
}
#endif
In between the two, we have all of our includes, typedefs, and function prototypes. I have a few questions, to see if I'm understanding this correctly:
If I have a C++ file A.hh which
includes a C header file B.h,
includes another C header file C.h,
how does this work? I think that
when the compiler steps into B.h,
__cplusplus
will be defined, so it
will wrap the code with extern "C"
(and __cplusplus
will not be
defined inside this block). So,
when it steps into C.h,
__cplusplus
will not be defined
and the code will not be wrapped in
extern "C"
. Is this correct?
Is there anything wrong with
wrapping a piece of code with
extern "C" { extern "C" { .. } }
?
What will the second extern "C"
do?
We don't put this wrapper around the .c files, just the .h files. So, what happens if a function doesn't have a prototype? Does the compiler think that it's a C++ function?
We are also using some third-party
code which is written in C, and does
not have this sort of wrapper around
it. Any time I include a header
from that library, I've been putting
an extern "C"
around the #include.
Is this the right way to deal with
that?
Finally, is this set up a good idea? Is there anything else we should do? We're going to be mixing C and C++ for the foreseeable future, and I want to make sure we're covering all our bases.
I know how to use extern "C"
but what are the conditions when you have to use it?
extern "C"
tells the C++ compiler not to perform any name-mangling on the code within the braces. This allows you to call C functions from within C++.
For example:
#include <string.h>
int main()
{
char s[] = "Hello";
char d[6];
strcpy_s(d, s);
}
While this compiles fine on VC++. But sometimes this is written as:
extern "C" {
#include <string.h>
}
I don't see the point. Can you give a real example where extern "C"
is necessary?
I'm taking a programming languages course and we're talking about the extern "C"
declaration.
How does this declaration work at a deeper level other than "it interfaces C and C++"? How does this affect the bindings that take place in the program as well?
Can C++ functions marked as Extern "C" throw?I've got C++ functions that I want to declare using extern "C"
even though they are only called in C++ code. Yes, I know this is strange but it's something I would like to do for consistency since we have mixed C and C++ declarations. I just want to make sure that declaring a C++ function as extern "C"
won't affect the behavior of throwing.
It would look something like this:
extern "C" void foo() {throw exception;}
int bar()
{
try
{
foo();
} catch (exception e) { return 1; }
}
how does extern "C" allow C++ code in a C file?
In order to use C++ code in a C file, I read that we can just do extern "C" { (where the c++ code goes here)}
, but when I try printing something out using cout, I keep getting an error because it does not recognize the library . I think I am just confused on how extern "C" allows you to use C++ code 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.
What does mean for a name or type to have a certain language linkage?According to (c) ANSI ISO/IEC 14882:2003, page 127:
Linkage specifications nest. When linkage specifications nest, the innermost one determines the language. A linkage specification does not establish a scope. A linkage-specification shall occur only in namespace scope (3.3). In a linkage-specification, the specified language linkage applies to the function types of all function declarators, function names, and variable names introduced by the declaration(s).
extern "C" void f1(void(*pf)(int));
// the name f1 and its function type have C language
// linkage; pf is a pointer to a C function
extern "C" typedef void FUNC();
FUNC f2;
// the name f2 has C++ language linkage and the
// function's type has C language linkage
extern "C" FUNC f3;
// the name of function f3 and the function's type
// have C language linkage
void (*pf2)(FUNC*);
// the name of the variable pf2 has C++ linkage and
// the type of pf2 is pointer to C++ function that
// takes one parameter of type pointer to C function
What does all this mean? For example, what linkage does the f2()
function have, C or C++ language linkage?
As pointed out by @Johannes Schaub, there is no real explanation of what this means in the Standard so it can be interpreted differently in different compilers.
Please explain the differences in the object file:
What exactly does putting extern "C"
into C++ code do?
For example:
extern "C" {
void foo();
}
Is extern "C" only required on the function declaration?
I wrote a C++ function that I need to call from a C program. To make it callable from C, I specified extern "C"
on the function declaration. I then compiled the C++ code, but the compiler (Dignus Systems/C++) generated a mangled name for the function. So, it apparently did not honor the extern "C"
.
To resolve this, I added extern "C"
to the function definition. After this, the compiler generated a function name that is callable from C.
Technically, the extern "C"
only needs to be specified on the function declaration. Is this right? (The C++ FAQ has a good example of this.) Should you also specify it on the function definition?
Here's an example to demonstrate this:
/* ---------- */
/* "foo.h" */
/* ---------- */
#ifdef __cplusplus
extern "C" {
#endif
/* Function declaration */
void foo(int);
#ifdef __cplusplus
}
#endif
/* ---------- */
/* "foo.cpp" */
/* ---------- */
#include "foo.h"
/* Function definition */
extern "C" // <---- Is this needed?
void foo(int i) {
// do something...
}
My issue may be the result of incorrectly coding something, or I may have found a compiler bug. In any case, I wanted to consult stackoverflow to make sure I know which is technically the "right" way.
static vs extern "C"/"C++"What is the difference between a static member function and an extern "C" linkage function ? For instance, when using "makecontext" in C++, I need to pass a pointer to function. Google recommends using extern "C" linkage for it, because "makecontext" is C. But I found out that using static works as well. Am I just lucky or...
class X {
public:
static void proxy(int i) {}
}
makecontext(..., (void (*)(void)) X::proxy, ...);
vs
extern "C" void proxy(int i) {}
makecontext(..., (void (*)(void)) proxy, ...);
EDIT: Can you show a compiler or architecture where the static member version does not work (and it's not a bug in the compiler) ?
Are extern "C" functions a separate type?From the C++11 draft, 7.5 (para. 1):
Two function types with different language linkages are distinct types even if they are otherwise identical.
So I can do overload based on language linkages:
extern "C" typedef void (*c_function)();
typedef void (*cpp_function)();
void call_fun(c_function f)
{
}
void call_fun(cpp_function f)
{
}
extern "C" void my_c()
{
}
void my_cpp()
{
}
int main()
{
call_fun(my_c);
call_fun(my_cpp);
}
But, with GCC 4.7.1 this sample code gives the error messages:
test.cpp: In function 'void call_fun(cpp_function)':
test.cpp:7:6: error: redefinition of 'void call_fun(cpp_function)'
test.cpp:4:6: error: 'void call_fun(c_function)' previously defined here
And with CLang++ :
test.cpp:7:6: error: redefinition of 'call_fun'
void call_fun(cpp_function f)
^
test.cpp:4:6: note: previous definition is here
void call_fun(c_function f)
^
Now the questions:
Is my understanding of the standard correct? Is this code valid?
Does anybody know if these are bugs in the compilers or if they are intentionally doing it that way for compatibility purposes?
I frequently come across C header files that contain extern "C"
guards,
but don't contain any actual functions. For example:
/* b_ptrdiff.h - base type ptrdiff_t definition header */
#ifndef __INCb_ptrdiff_th
#define __INCb_ptrdiff_th
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _PTRDIFF_T
#define _PTRDIFF_T
typedef long ptrdiff_t;
#endif /* _PTRDIFF_T */
#ifdef __cplusplus
}
#endif
#endif /* __INCb_ptrdiff_th */
I know that extern "C"
prevents name mangling on functions, but does it also prevent against other interfacing issues on variable and type declarations?
Is the use of extern "C"
in the example above meaningless in terms of resulting compatibility?
As it is known, declaring extern "C"
to C++ function makes its name have C linkage, enabling C code to link.
My question is - are there other programming languages we can make C++ function names have linkage to, something like extern "Lisp"
or extern "FORTRAN"
?
If not, why? What is the internal structure behind the "C"
, that makes the limitations?
What are the alternatives?
Is it safe to "play" with parameter constness in extern "C" declarations?Suppose I'm using some C library which has a function:
int foo(char* str);
and I know for a fact that foo()
does not modify the memory pointed to by str
. It's just poorly written and doesn't bother to declare str
being constant.
Now, in my C++ code, I currently have:
extern "C" int foo(char* str);
and I use it like so:
foo(const_cast<char*>("Hello world"));
My question: Is it safe - in principle, from a language-lawyering perspective, and in practice - for me to write:
extern "C" int foo(const char* str);
and skip the const_cast
'ing?
If it is not safe, please explain why.
Note: I am specifically interested in the case of C++98 code (yes, woe is me), so if you're assuming a later version of the language standard, please say so.
extern-c