Why is multiple definition of a const global variable allowed in C++ and not in C?

Ashwin Nanjappa picture Ashwin Nanjappa · May 30, 2011 · Viewed 9.1k times · Source

Multiple definition of a global variable is not allowed in C or C++ due to the One Definition Rule. However, in C++ a const global variable can be defined in multiple compilation units with no error. This is not the same as in C.

Why does C++ allow this while C does not? Why does the usage and behaviour of a const global differ from a non-const global in this way in C++ compared to C? What is happening under the covers with C++ and C with respect to const?

For example this is allowed in C++, but wrong in C:

// Foo.cpp
const int Foo = 99;

// Main.cpp
const int Foo = 99;
int main()
{
    cout << Foo << endl;
    return 0;
}

And this is fine with C, but wrong with C++:

// Foo.cpp
const int Foo = 99;

// Main.cpp
extern const int Foo;
int main()
{
    cout << Foo << endl;
    return 0;
}

Answer

Nawaz picture Nawaz · May 30, 2011
// Foo.cpp
const int Foo = 99;

// Main.cpp
const int Foo = 99;

const variable at namespace scope has internal linkage. So they're basically two different variables. There is no redefinition.

From @David's comment, 3.5/3 [basic.link]:

A name having namespace scope (3.3.5) has internal linkage if it is the name of
— an object, reference, function or function template that is explicitly declared static or,
— an object or reference that is explicitly declared const and neither explicitly declared extern nor previously declared to have external linkage; or
— a data member of an anonymous union.


In the second case, you should be doing this (correct way):

//Foo.h
extern const int Foo; //use extern here to make it have external linkage!

// Foo.cpp
#include "Foo.h"
const int Foo = 99; //actual definition goes here

// Main.cpp
#include "Foo.h"
int main()
{
   cout << Foo << endl;
}