繁体   English   中英

C ++标准:命名空间范围的constexpr变量是否具有内部链接?

[英]C++ standard: do namespace-scoped constexpr variables have internal linkage?

想象一下,我们有一个包含以下内容的标题foo.h

#ifndef FOO_H_
#define FOO_H_

namespace foo {
constexpr std::string_view kSomeString = "blah";
}

#endif  // FOO_H_

foo::kSomeString保证在包含foo.h任何翻译单元中都有内部链接? 这在C ++ 11和C ++ 17之间有所不同吗?

在草案标准[basic.link] / 3中

具有命名空间作用域的名称具有内部链接,如果它是非易失性const限定类型的非内联变量的名称,该变量既未显式声明为extern,也未声明为具有外部链接[...]

但我不知道constexpr算作“const-qualified”。 标准是否在某处说出来?

假设这保证具有内部链接,看起来ODR对此用法没有问题,对吧? (与此答案中的内容形成鲜明对比。)

是的,对象声明的constexpr意味着对象是const [dcl.constexpr] / 9 是的,这意味着您的示例中的kSomeString具有内部链接。

我们在这里讨论的ODR违规种类不是kSomeString本身的定义,而是其他试图使用它的定义。 正是由于内部联系,存在一个问题。 考虑:

void f(const std::string_view &);

inline void g() { 
    f(foo::kSomeString); 
}

如果包含在多个翻译单元中,这是ODR违规,主要是因为每个翻译单元中g的定义引用了不同的对象。

您对kSomeString使用是完全有效的。

首先要做的事情; TC解释说,你的对象是const限定的。 它还是文字类型 ,因为它有一个constexpr构造函数。 因此,如果在头文件中定义的函数中使用它,则标准中的以下异常适用(第3.2章):

内联函数可以有多个定义,外部链接(7.1.2),非静态函数模板(14.5.6),(...)在程序中,每个定义出现在不同的翻译单元中,并提供这些定义满足以下要求。 鉴于这样一个名为D的实体在多个翻译单元中定义,那么

  • D的每个定义应由相同的令牌序列组成;
  • 在D的每个定义中,根据3.4查找的相应名称,应指在D的定义中定义的实体,或者在重载决议(13.3)之后和部分模板专业化匹配之后应引用同一实体(14.8) .3), 除了如果对象在D的所有定义中具有相同的文字类型,并且该对象用常量表达式(5.19)初始化,并且值(但不使用对象的地址),并且对象在D的所有定义中具有相同的值 ;
  • (......)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM