3

I have a header file that contains the following definition

const std::string error[] = {"a", "b"};

Now I'm including this file in two different translation units and compiling the source codes. Everything works, but why? This is expected to break one definition rule.

Now even more interesting, I'm changing the type

const char* error[] = {"a", "b"};

and here it is, expected error

multiple definition of `error'

It works the same way as for std::string for int, char, short and other integral types. What is this?

axe
  • 2,331
  • 4
  • 31
  • 53

3 Answers3

12

const gives namespace-scoped variables internal linkage, that's why it works, effectively the same as

static const std::string error[] = {"a", "b"};

The second one doesn't work because it's not the variable that is const, but the chars it consists of.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • 1
    Didn't know that const gives an internal linkage. Thanks. Is it mentioned in standard? – axe Nov 25 '13 at 14:39
  • 2
    Yes, found it. `Objects declared const and not explicitly declared extern have internal linkage.` – axe Nov 25 '13 at 14:41
  • @axe What's the reference? – BoBTFish Nov 25 '13 at 14:47
  • Never mind. It's 7.1.1 Storage class specifiers [dcl.stc], paragraph 7. – BoBTFish Nov 25 '13 at 14:49
  • Also note that this is one of the few places where C++ breaks compatibility with C. See [this question](http://stackoverflow.com/questions/998425/why-does-const-imply-internal-linkage-in-c-when-it-doesnt-in-c) for details and rationale. – ComicSansMS Nov 25 '13 at 14:51
2

Global variables declared const have internal linkage, as if they were also declared static. You can define internal variables with the same name in different translation units, so that's what happens in your first example - each unit that includes the header gets its own copy of the array.

The second example is not const - the pointers point to constant objects, but are themselves mutable. So this array has external linkage, and is subject to the One Definition Rule.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
0

From MSDN

In C, constant values default to external linkage, so they can appear only in source files. In C++, constant values default to internal linkage, which allows them to appear in header files.

Sergei Nikulov
  • 5,029
  • 23
  • 36