1

What does the author mean about "extern linkage" and "C language linkage" in the following paragraph, extracted from [1].

"There are two different forms of the extern C declaration: extern C as used above, and extern C { … } with the declarations between the braces. The first (inline) form is a declaration with extern linkage and with C language linkage; the second only affects language linkage. The following two declarations are thus equivalent:"

Can you further elaborate what he's trying to explain with this example?

[1] http://tldp.org/HOWTO/C++-dlopen/thesolution.html

JohnTortugo
  • 6,356
  • 7
  • 36
  • 69
  • 1
    Zack's & paxdiablo's answers are both good. The author of the dlopen doc you link to mentions that the extern "C" declaration prevents name mangling; more correctly, it selects C style name mangling, which depending on your compiler may be "nothing" or may be "prepend with underscore". Another thing that I've not seen mentioned in that doc or the answers below is that "C" linkage also has implications with the calling convention used for a function, i.e. where the arguments to the function are placed (order on the stack, etc) and who's responsible for cleanup (caller/callee). – phonetagger May 05 '12 at 04:21

2 Answers2

4

What the author is saying relates to these two lines:

extern "C" int foo;
extern "C" { int bar; }

foo is a variable declared but not defined. It exists elsewhere. On the other hand, bar is both declared and defined.

Think of a declaration as just stating that something exists somewhere but not actually creating it. Definition is therefore declaration plus bringing that thing into existence.

The latter one is exactly the same as int bar; but will "publish" the variable with C linkage. For example, a function int max (int a, int b); may be published as _max in C language linkage and _max$$int$int in C++ language linkage (to allow more than one function with the same name).

Note that "publishing" in this context is how the function looks to the linker, so that your code can link to it. Without C language linkage, it's usually rather difficult to link C code with C++ libraries.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • 1
    uhmmm I think I got it. when I use: `extern "C" type id;` I'm saying two things: link with "C" convention and also that `id` has an definition somewhere else. But when I use: `extern "C" { type id; }` I'm exporting `id` with "C" convention and I'm also saying that I'm defining `id` here. right? – JohnTortugo May 05 '12 at 03:50
2

Clumsy wording, yeah. What he's trying to get at is,

extern "C" int foo();

is the same as

extern "C" { extern int foo(); }

but not the same as

extern "C" { int foo(); }

... except that there is no practical difference between "extern int foo();" and "int foo();" at file scope in C++, so you are entirely forgiven for scratching your head. Here's a case where it actually makes a difference:

extern "C" const int x = 12;
extern "C" { const int y = 12; }

x will be visible outside the translation unit, y won't.

zwol
  • 135,547
  • 38
  • 252
  • 361
  • 1
    Is that right about `y`? I thought default linkage at file-level was external, or is that not the case for `const` variables in C++? – paxdiablo May 05 '12 at 03:35
  • 2
    @paxdiablo: `const` variables at namespace scope have internal linkage by default in C++. See 3.5p3. – Ben Voigt May 05 '12 at 03:50
  • @Ben, you're right (of course). Introducing a new namespace-scope (including global namespace) const without explicit extern marks it as internal linkage - I learn something new here most every day. Cheers. – paxdiablo May 05 '12 at 05:47