Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  • a function's name with C language linkage and C++ language linkage.
  • a function's type with C language linkage and C++ language linkage.
like image 453
artyom.stv Avatar asked Apr 23 '11 11:04

artyom.stv


People also ask

What does linkage mean in C?

In C, all identifiers are lexically (or statically) scoped. Linkage : Linkage describes how names can or can not refer to the same entity throughout the whole program or one single translation unit.

What are the types of linkages in C?

There are three types of linkage: external linkage , internal linkage and no linkage . Anything internal to a function—its arguments, variables and so on—always has no linkage and so can only be accessed from inside the function itself.

What external linkage is only used in one translation unit?

As dudewat said external linkage means the symbol (function or global variable) is accessible throughout your program and internal linkage means that it is only accessible in one translation unit.

What does extern mean in CPP?

In a non- const global variable declaration, extern specifies that the variable or function is defined in another translation unit. The extern must be applied in all files except the one where the variable is defined. In a const variable declaration, it specifies that the variable has external linkage.


2 Answers

Language linkage is the term used for linkage between C++ and non-C++ code fragments. Typically, in a C++ program, all function names, function types and even variable names have the default C++ language linkage.

A C++ object code can be linked to another object code which is produced using some other source language (like C) using a predefined linkage specifier.

As you must be aware of the concept of name mangling, which encodes function names, function types and variable names so as to generate a unique name for them. This allows the linker to differentiate between common names (as in the case of function overloading). Name mangling is not desirable when linking C modules with libraries or object files compiled with a C++ compiler. To prevent name mangling for such cases, linkage specifiers are used. In this case, extern "C" is the linkage specifier. Let's take an example (c++ code mentioned here):

typedef int (*pfun)(int);  // line 1 extern "C" void foo(pfun); // line 2 extern "C" int g(int)      // line 3 ... foo( g ); // Error!        // line 5 

Line 1 declares pfun to point to a C++ function, because it lacks a linkage specifier.

Line 2 therefore declares foo to be a C function that takes a pointer to a C++ function.

Line 5 attempts to call foo with a pointer to g, a C function, a type mis-match.

Diff in function name linkage:

Let's take two different files:

One with extern "c" linkage (file1.cpp):

#include <iostream> using namespace std;  extern "C" { void foo (int a, int b) {     cout << "here"; } }  int main () {     foo (10,20);     return 0; } 

One without extern "c" linkage (file2.cpp):

#include <iostream> using namespace std;  void foo (int a, int b) {     cout << "here"; }  int main () {     foo (10,20);     return 0; } 

Now compile these two and check the objdump.

# g++ file1.cpp -o file1 # objdump -Dx file1  # g++ file2.cpp -o file2 # objdump -Dx file2 

With extern "C" linkage, there is no name mangling for the function foo. So any program that is using it (assuming we make a shared lib out of it) can directly call foo (with helper functions like dlsym and dlopen) with out considering any name mangling effects.

0000000000400774 <foo>:   400774:   55                      push   %rbp   400775:   48 89 e5                mov    %rsp,%rbp .... ....   400791:   c9                      leaveq    400792:   c3                      retq     0000000000400793 <main>:   400793:   55                      push   %rbp   400794:   48 89 e5                mov    %rsp,%rbp   400797:   be 14 00 00 00          mov    $0x14,%esi   40079c:   bf 0a 00 00 00          mov    $0xa,%edi   4007a1:   e8 ce ff ff ff          callq  400774 <foo>   4007a6:   b8 00 00 00 00          mov    $0x0,%eax   4007ab:   c9                      leaveq  

On the other hand, when no extern "C" is being used, func: foo is mangled with some predefined rules (known to compiler/linker being used) and so an application can not directly call it from it specifying the name as foo. You can however call it with the mangled name (_Z3fooii in this case) if you want, but nobody use it for the obvious reason.

0000000000400774 <_Z3fooii>:   400774:   55                      push   %rbp   400775:   48 89 e5                mov    %rsp,%rbp  ... ...   400791:   c9                      leaveq    400792:   c3                      retq     0000000000400793 <main>:   400793:   55                      push   %rbp   400794:   48 89 e5                mov    %rsp,%rbp   400797:   be 14 00 00 00          mov    $0x14,%esi   40079c:   bf 0a 00 00 00          mov    $0xa,%edi   4007a1:   e8 ce ff ff ff          callq  400774 <_Z3fooii>   4007a6:   b8 00 00 00 00          mov    $0x0,%eax   4007ab:   c9                      leaveq    4007ac:   c3                      retq    

This page is also a good read for this particular topic.

A nice and clearly explained article about calling convention: http://www.codeproject.com/KB/cpp/calling_conventions_demystified.aspx

like image 83
Vikram.exe Avatar answered Sep 30 '22 23:09

Vikram.exe


"the name f2 has C++ language linkage" In C++ language linkage not only the name of the function defines it but also the type of it arguments and the return value. in this case you have: void f2(void); but you can define with it: void f2(int a); without conflict because the linkage will see them as different types, a thing you wouldn't be able to do in C language.

"the function's type has C language linkage" I don't know the details but I know the high level of it. Basically it makes a C++ compiled function linkable from C. If I remember correctly In C and in C++ the way the parameters are passed to a function is different. In this case the function f2 will pass the parameters as C compiler does this. this way the function will be linkable both from C and C++.

like image 33
Roee Gavirel Avatar answered Sep 30 '22 23:09

Roee Gavirel