Will my program contain 100 copies of each string and array literal if I include it into 100 units? Or will only the pointers and values be copied?
The standard does not promise consolidation of string literals, so it's up to the implementation. A simple test using GCC 5.1.1 on GNU/Linux showed that the string literals are not consolidated in an unoptimized build, but are consolidated when -O
or -Os
is used. But that is just merging the actual char
arrays. To the extent that the compiler doesn't optimize away the storage for the pointer, or for the numerical constants (if they are local to the translation unit, not ODR-used, and of POD type, they are obvious candidates for elimination under the as-if rule), however, the compiler may not be able to consolidate them easily. The standard requires them to be different objects and hence must have different addresses. The as-if rule may still allow their removal, even if you were to take their addresses, but this would generally require global program optimization aka link-time optimization, including libraries, that the implementation may not support, support only in a limited fashion, and/or only depending on compiler and linker settings. In other words, it just might happen under the right circumstances, but it is much more likely not to happen.
My own test indicates that GCC 5.1.1 does not consolidate static const unsigned int
objects exposed by const
ref, even with -Os -flto
(optimize for size and enable link-time optimization). I would frankly be surprised if any contemporary implementation did perform this difficult and obscure optimization.
(also I'm guessing the 'static' is redundant in this usage, but I like to put it there anyway)
It's not redundant if you have multiple translation units because you would otherwise run afoul of the one definition rule (ODR). As a side note, however, static
at namespace scope has been considered syntactically obsolete for a long time (consider using anonymous namespaces, introduced in C++98, instead).
(in response to Cheers and hth. - Alf)
If you want to ensure only one copy of each constant, or even no copy, then you can use a class template, like this:
No such luck. There's no guarantee in the standard about how much space is used for the templates. All the template does guarantee is that only one of the potentially many copies is used – or appears to be used, under the as-if rule. In fact, it's worse than that because at least GCC 5.1.1 in fact does not remove a redundant static const unsigned int
even with -Os -flto
on my system. This means with two translation units, the initializer value for the unsigned int
can be found in two separate locations, even though only one of them is used (all pointers and references refer to this location only).