I know that static
const
class
members can be initialised in headers only. Is it the same for namespaces ? For example, is it valid to write :
namehuman.hpp
namespace namehuman
{
string const human("human");
}
main.cpp
#include "namehuman.hpp"
cout << namehuman::human << endl;
I am wondering if all files including the header file will have their own copy of string
human, or if human will be a true global variable (not copied many times). In order to avoid each including file making its copy, am I obliged to use extern
?
Constants have internal linkage. Thus any compilation unit that includes the header with the definition of the constant will have its own instance of the object.
According to the C++ Standard (3.5 Program and linkage)
3 A name having namespace scope (3.3.6) has internal linkage if it is the name of
...
— a non-volatile variable that is explicitly declared const or constexpr and neither explicitly declared extern nor previously declared to have external linkage; or
If you want a constant with external linkage, you must declare it with the specifier extern
, and define it in a compilation unit.
I think that will define the human
several times, so it can happen that this causes an ODR violation (see below). It's usually best to only declare it in the header
extern const string human;
and add the definition to the implementation file
string human("human");
Be careful about the initialization order fiasco and the equivalent when closing the application.
An ODR violation can be caused when an inline function with external linkage ODR-uses human
. I think that, since that is really easy to do and there is no way to guard against it, it is best to define constant strings in the implementation file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With