Question

I have this situation:

// Test.h
extern const int param;
class Test
{
private:
    int i;
public:
    int foo();
};

and

// Test.cpp
#include "Test.h"
int Test::foo() { return param*10; }

and

// core.h
#include "Test.h"
const int param = 1; // should have internal linkage later in core.cpp
int do_stuff ();

and

// core.cpp
#include "core.h"
int do_stuff () { Test obj; return obj.foo(); }
int main() { return do_stuff(); }

However there is no linker error. How does the linker see for Test.cpp the const int param which is through core.h defined in core.cpp having internal linkage (default for const definitions)?

When I rewrite core.h like this (change two lines):

// core.h
const int param = 1;
#include "Test.h"
int do_stuff ();

there comes a linker error for missing param. And then, when I change it like this:

// core.h
extern const int param = 1;
#include "Test.h"
int do_stuff ();

all works again.

I thought, that maybe in original situation there is an automatic inlining of class Test inside core.cpp, so that Test.cpp is as not existent and the whole code is in core.cpp, so that all works. But why should it then be dependent of changing the two lines in core.h?

Was it helpful?

Solution

Your assumption about internal linkage for const definitions is not always true. See the standart section 3.5 Program linkage, p. 3 (I'm quoting N3690):

A name having namespace scope (3.3.6) has internal linkage if it is the name of

  • a variable, function or function template that is explicitly declared static; or,

  • a non-volatile variable that is explicitly declared const or constexpr and neither explicitly declared extern nor previously declared to have external linkage; or

  • a data member of an anonymous union.

So for the first case param has external linkage and everything is okay.

For the second case, there is an internal-linked param in core.cpp, but there is another declared-only param having external linkage but no definition.

In the third case, there is one param again.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top