There are two points of view that need to be considered, namely: visibility and addressing.
Note that these two are orthogonal, since you can actually declare the variable as initialized and still define it in the translation block to have an effective memory address.
Visibility
Visibility affects the use of a variable and has some technical implications.
For use in a template as a parameter of a non-type type template, the value must be visible at the point of use. Also, in C ++ 11, this may be required to use constexpr . Otherwise, this value is not required to be visible.
Technically visible value can trigger optimization from the compiler. For example, if (A::member) is trivially false, so the check can be eliminated. This is usually called continuous distribution. Although this may seem successful, at first glance there is a profound effect: all clients of the header file are potentially dependent on this value, and thus, any change to this value means that they must be recompiled. If you deliver this header as part of a shared library, it means that changing this value aborts the ABI.
Decision
The rule here is quite simple: if the variable can be addressed (either passed by pointer or by reference), then it must be somewhere in memory. This requires a definition in one translation unit.
source share