Use of extern 'C' in C++

  • 2020-04-02 02:37:35
  • OfStack

As anyone who has studied C++ knows, The extern keyword can be placed before a variable or function to indicate that the variable or function's definition is in another file, prompting the compiler to look for the definition in another module when it encounters the variable or function. This is where the scope of action comes in. Also, extern can be used with "C" as a link indicator. In this paper, an example is given as follows:

C++ Name modification (Name Mangling)

Let's start with C++ overloading, where function overloading refers to several functions with the same name and different parameter lists. So how does the C++ compiler distinguish between these overloaded functions when generating obj intermediate/object files? You can combine the original function Name with the parameter information to produce a unique internal Name, a technique called Name Mangling. There is no standard for naming rules, so different compilers have different naming rules.

Here is a set of functions where the f() function is overloaded:


int f (void) { return 1; } 
int f (int) { return 0; } 
void g (void) { int i = f(), j = f(0); } 

F (void) and f(int) are different functions and have nothing to do with each other except that they have the same name. When generating obj object files, in order to distinguish them, the C++ compiler modifies the name according to the parameter information:


int __f_v (void) { return 1; } 
int __f_i (int) { return 0; } 
void __g_v (void) { int i = __f_v(), j = __f_i(0); }

Note that g() is also modified by the name, although there are no name conflicts. Name modifies any symbol applied to C++.

Why use extern "C"?

There is no Name modification in C because C does not support function overloading. However, if C code is included in C++, the C++ compiler will also modify the name of the functions in C code at compile time. If the function name changes, the corresponding functions will not be found in the C runtime, resulting in a link error.


//Save the following code as a.cpp file and compile it with the C++ compiler
int printf(const char *format,...); 
  
int main() 
{ 
  printf("GeeksforGeeks"); 
  return 0; 
}

Output:


/tmp/ccQBO9Im.o : in the function ' main' In:  
test.cpp:(.text+0xf) : the ' printf(char const*, ...)' An undefined reference  
collect2:  Error: ld  return  1 

To prevent the C++ compiler from modifying C code by name, we link the C code with extern "C" to tell the compiler not to modify this part of the code by name when generating intermediate files, but instead to generate intermediate symbolic names that conform to the rules of C.


extern "C" 
{ 
  int printf(const char *format,...); 
} 
 
int main() 
{ 
  printf("Hello!"); 
  return 0; 
}

With the extern "C" link indication added, the above code should work.

Attachment: all c-style header files (stdio. H, string. H... Both are declared under extern "C" as follows:


#ifdef __cplusplus  
extern "C" { 
#endif 
   
#ifdef __cplusplus 
} 
#endif

Related articles: