Name Mangling and extern in C++
Name Mangling and Function Overloading:
Function overloading is a feature offered by C++. As long as each function accepts various parameters, we can use this to write many functions with the same name. Function overloading cannot be understood by lower-level languages (such as C or assembly) or tools (such as linker). Each function name in these languages must be distinct for functions to be distinguishable from one another solely by name.
Functions are distinguished in C++ using both their name and parameters. For each function, a brand-new name is generated. The original C++ function's name and parameters determine the new name. It will always produce a unique name when given the name of a function and a set of parameters.
Even if the original C++ function name remains the same, if parameters (number of parameters, type of parameters, or order of parameters) change, a new name will be generated. Name mangling is the term used to describe this encoding of the function name.
The name-mangling method is compiler-dependent. Compilers can employ a variety of tactics. A name that has been distorted by one compiler might not have been distorted by other compilers.
Take into account the following Name Mangling example, which contains several f() function declarations:
// To demonstrate function overloading
// Name Mangling
int fun(void)
{
return 0;
}
int fun(int)
{
return 1;
}
void good(void)
{
int i = fun(), j = fun(0);
}
We can easily see that the above two functions, which have the same name, "fun," but the parameter is different, then the compiler will generate a new name for differentiating between the same functions, but the parameter will be the same which prevents naming conflicts and makes it possible to overload functions or variables with the same name.
The names listed above may be altered by some C++ compilers to become,
// To demonstrate function overloading
// Name Mangling
int __fun_v(void)
{
return 0;
}
int __fun_i(int)
{
return 1;
}
void __good_v(void)
{
int i = __fun_v(), j = __fun_i(0);
}
Explanation:
- In the above functions, we can easily see that compiler is generated a new name for functions which is not similar.
- Before the compilation, Previously the 1st function name was "fun", but after the compilation, the function name is changed from "f" to "__fun_v”.
- Similar things happen in the 2nd function and 3rd function that compiler generates the function name with the same arguments when this program is compiled.
- So this is called Name Mangling.
Note: function overloading is not supported in C, care must be taken to ensure that no symbol names are modified while linking C code to C++.
Extern “C” in C++:
Extern "C" is a keyword in C++ that is used to indicate that the following function or variable should not be mangled. This allows C++ code to interoperate with C code, as C code does not use name mangling. When a function or variable is declared with extern "C", its name will remain the same as it would in C, making it accessible to C code.
When code is placed in the extern "C" block, the C++ compiler makes sure the function names are preserved and that the compiler emits a binary file with the names of the functions unaltered, just like a C compiler would.
In order to prevent C++ functions from being altered so that they can be called from C, the extern "C" linkage specifier can also be used.
For example, consider the following C++ code:
int add(int a, int b)
{
return a + b;
}
Without extern "C", the compiler would mangle the name of the function "add" to include information about its type and other attributes, such as the number and types of its parameters. This would make the function difficult or impossible for C code to call.
To prevent this, the function can be declared with extern "C" like this:
extern "C" int add(int a, int b)
{
return a + b;
}
This tells the compiler not to mangle the name of the function, and it will remain the same as it would in C. This makes it accessible to C code and can be called from C code without any issues.
Extern "C" is often used in header files shared between C++ and C code. For example, a C++ library might define several functions with the extern "C" in a header file, which can then be included in C code and used without any issues.
It's worth noting that extern "C" applies only to the function or variable that immediately follows it, and it's not a storage class specifier like extern, static or auto. It's also important to note that while extern "C" works for both functions and variables, not all C compilers support it.
Conclusion:
- Since C++ allows for function overloading, extra information must be added to function names (a process known as name mangling) in order to prevent conflicts in binary code.
- Name mangling is a technique used in C++ to encode the information about a function or variable's type, scope, and other attributes in its name, which allows the compiler to generate unique names for functions or variables that have the same name but different types or scopes.
- Since function overloading is not supported by C, function names cannot be modified. The extern "C" block is supported by C++ to prevent linking issues. The extern "C" block's names are protected from alteration by the C++ compiler.
- Extern "C" is a keyword in C++ that is used to indicate that the following function or variable should not be mangled, making it accessible to C code and allowing C++ code to interoperate with C code. It's a useful technique for creating libraries that can be used by both C and C++ code.