I'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.
External variables are also known as global variables. These variables are defined outside the function. These variables are available globally throughout the function execution. The value of global variables can be modified by the functions. “extern” keyword is used to declare and define the external variables.
Extern is a keyword in C programming language which is used to declare a global variable that is a variable without any memory assigned to it. It is used to declare variables and functions in header files. Extern can be used access variables across C files.
The extern must be applied to all declarations in all files. (Global const variables have internal linkage by default.) extern "C" specifies that the function is defined elsewhere and uses the C-language calling convention. The extern "C" modifier may also be applied to multiple function declarations in a block.
No. But a global variable can be declared extern locally.
By attaching extern "C"
to your C++ declarations (objects and functions alike) you give them "C linkage" - make them accessible from C code. If you omit this "language linkage" specification, the compiler doesn't do any effort to do proper linkage. In the case of functions, this results in failed linkage, because of mangling. In the case of global variables, everything might work fine, because variables don't need mangling.
However, on my system (MS Visual Studio), linkage between C and C++ doesn't work if I "forget" to specify the extern "C"
linkage specification in the C++ header file. Example error message:
error LNK2001: unresolved external symbol "int global" (?_global)
While, when I examine a compiled C++ source code that contains the definition of global
with the dumpbin
utility, I see
00B 00000014 SECT4 notype External | ?global@@3HA (int global)
So MS Visual Studio mangles the names of global variables, unless they have C linkage - this makes C linkage specifications mandatory.
In addition, consider the following example:
namespace example {
int global;
}
If the global variable is inside a namespace, C code will not get access to it. In this case, all compilers will require the proper linkage specification on the C++ declaration:
namespace example {
extern "C" int global;
}
Conclusion:
Use extern "C"
when you want C linkage - doesn't matter if it's a function or a global variable. If it's a global variable, it may work regardless, but it's not guaranteed (and may be dangerous).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With