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;
}
Assume this code exists in a header file that will be included in multiple translation units.
My understanding of inline functions is that they must be exactly the same in every translation unit.
My understanding of constants as used above, is that they are implictly static
ie internal linkage. These means each translation unit gets its own copy.
As the inline functions above rely on these constants, which of these functions, if any, are correct?
If included into multiple translation units, the only function that is valid is
f_a1
.The relevant clause is [basic.def.odr]/6, which states that an
inline
function can appear in multiple translation units, but only given that:As the objects are
const
, they have internal linkage per [basic.link]/3:However, taking the address of or forming a reference to a variable (e.g. for argument passing) is odr-use, so
f_a2
andf_b2
are invalid.f_b1
is also invalid, as theostream
output operator forstd::string
takes its argument by reference; and even if it took its argument by value the implicitly called copy constructor would take its argument by reference.f_a1
is OK because theint
stream-out operator takes its argument by value, and copying the value of anint const
is not odr-use.