So I know that in C++ constants get, by default, different linkage than variables. That's why I must not put
int foo;
in some header – the linker will rightly complain about multiple definitions. OTOH, I can write
const int bar = 42;
in a header, and the compiler makes sure there's only one definition of bar
.
With integral constants, it is easy to see how the compiler deals with this – at least as long as nobody takes the address of bar
or does some other funny thing requiring it to assign storage for it). However, what if someone does? And what if it isn't an integral but something that needs code to be executed at runtime? Assume I put this into a header:
const std::string baz = "h2g2";
Assuming no small string optimizations, this needs to allocate dynamic memory at runtime, so code needs to be executed, the address needs to be stored somewhere, etc.
I assume I would then end up with one definitions of baz
per translation unit, only that the compiler assigns internal linkage to it to prevent the linker from complaining? Or am I missing something?
Note: I am not interested in constexpr
, just in plain old C++ constants, as they existed since the 80s and were codified in C++98. (However, if a comprehensive answer would include how this all fits together with constexpr
, I wouldn't complain about that.)
Declaring an object (at namespace scope) as const
in C++ assigns it internal linkage by default.
If you declare (and define because of the initialization)
const std::string baz = "h2g2";
into a header you will have a statically linked string per each translation unit. The address would have to be stored in each translation unit (different addresses per different non-heap stored char literals - read only memory)
Edit: As a C++11 digression constexpr
implies const
since it means "suitable for constant expressions evaluation", thus it should have internal linkage as well. [Nb. I'm not mentioning C++14]
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