头文件中的内联函数可以使用具有内部链接的常量吗? [英] Can an inline function in a header file use a constant which has internal linkage?
问题描述
请考虑以下代码:
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.
理解上面使用的常量,是它们暗示 static
即内部链接。
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?
推荐答案
如果包含在多个翻译单元中,唯一有效的函数是 f_a1
。
If included into multiple translation units, the only function that is valid is f_a1
.
相关的子句是 [basic.def.odr] / 6,它说明 inline
函数可以出现在多个翻译单元中,但只能是:
The relevant clause is [basic.def.odr]/6, which states that an inline
function can appear in multiple translation units, but only given that:
[...]非挥发性
const
对象与内部或没有链接,如果对象在D,
的所有定义中具有相同的字面类型,并且对象初始化与常量表达式(5.19),并且对象不是odr使用,并且
对象在D的所有定义中具有相同的值;
[...] a name can refer to a non-volatile
const
object with internal or no linkage if the object has the same literal type in all definitions of D, and the object is initialized with a constant expression (5.19), and the object is not odr-used, and the object has the same value in all definitions of D;
由于对象是 const
,它们具有 [basic.link] / 3的内部链接:
As the objects are const
, they have internal linkage per [basic.link]/3:
有一个命名空间范围(3.3.6)的名称有内部链接,如果它是[...]的名称
- 一个非易失性变量,显式声明为const或constexpr,并且没有明确声明
extern也没有声明为外部链接[...]
A name having namespace scope (3.3.6) has internal linkage if it is the name of [...]
— a non-volatile variable that is explicitly declared const or constexpr and neither explicitly declared extern nor previously declared to have external linkage [...]
但是,获取变量的地址或形成对变量的引用(例如,传递参数)是 odr-use ,因此 f_a2
和 f_b2
无效。 f_b1
也无效, ostream
输出操作符 std :: string
引用它的参数;并且即使它采用其值的参数,隐式调用的复制构造函数将通过引用获取其参数。 f_a1
是可以的,因为 int
流出操作符以值为参数接受其参数, c $ c> int const 不是odr使用。
However, taking the address of or forming a reference to a variable (e.g. for argument passing) is odr-use, so f_a2
and f_b2
are invalid. f_b1
is also invalid, as the ostream
output operator for std::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 the int
stream-out operator takes its argument by value, and copying the value of an int const
is not odr-use.
这篇关于头文件中的内联函数可以使用具有内部链接的常量吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!