Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

extern and extern "C" for variables

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.

like image 517
Thenewstockton Avatar asked Jul 01 '16 09:07

Thenewstockton


People also ask

What is extern variable in C?

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.

Does extern make a variable global?

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.

When should I use extern C?

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.

Can a local variable be extern in C?

No. But a global variable can be declared extern locally.


1 Answers

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

like image 183
anatolyg Avatar answered Nov 06 '22 19:11

anatolyg