头文件中的内联函数可以使用具有内部链接的常量吗? [英] Can an inline function in a header file use a constant which has internal linkage?

查看:298
本文介绍了头文件中的内联函数可以使用具有内部链接的常量吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆