Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do non-integral constants work in C++?

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.)

like image 656
sbi Avatar asked Jul 16 '14 13:07

sbi


1 Answers

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]

like image 159
Marco A. Avatar answered Sep 28 '22 09:09

Marco A.