Can an inline function in the header file use a constant that has an internal relationship?

Consider the following code:

const int a = 0; const std::string b = "hi"; inline void f_a1() { std::cout << a; } inline void f_b1() { std::cout << b; } inline void f_a2() { std::cout << &a; } inline void f_b2() { std::cout << &b; } 

Suppose this code exists in a header file that will be included in several translation units.

My understanding of built-in functions is that they must be exactly the same in every translation unit.

My understanding of constants, as used above, is that they are implicitly static i.e. internal connection. This means that each translation unit receives its own copy.

Since the built-in functions above rely on these constants, which of these functions, if any, are correct?

+6
source share
1 answer

If it is included in several translation units, the only valid function is f_a1 .

The corresponding sentence [basic.def.odr] / 6, which states that the inline function can be displayed in several translation units, but only on condition that:

[...] the name can refer to a non-volatile const object with internal or no binding if the object has the same literal type in all definitions of D and the object is initialized with the constant expression (5.19) and the object is not used as odr, but an object has the same meaning in all definitions of D;

Since the objects are const , they have an internal connection at [basic.link] / 3:

A name that has a namespace scope (3.3.6) has an internal relationship if that name [...]
- an immutable variable that is explicitly declared as const or constexpr and is not explicitly declared extern or previously declared to have an external connection [...]

However, using an address or linking to a variable (for example, to pass an argument) is odr-use, so f_a2 and f_b2 are not valid. f_b1 also invalid because the ostream output ostream for std::string takes its argument by reference; and even if he accepted his argument by value, the implicitly called copy constructor would accept its argument by reference. f_a1 OK, because the stream operator int takes its argument by value, and copying the value of int const is not acceptable.

+6
source

Source: https://habr.com/ru/post/983103/


All Articles