其他分享
首页 > 其他分享> > C标准:做命名空间范围的constexpr变量有内部联系吗?

C标准:做命名空间范围的constexpr变量有内部联系吗?

作者:互联网

想象一下,我们有一个包含以下内容的标题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中说

A name having namespace scope has internal linkage if it is the name of […] a non-inline variable of non-volatile const-qualified type that is neither explicitly declared extern nor previously declared to have external linkage […]

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

假设这保证具有内部链接,看起来ODR对此用法没有问题,对吧? (与this answer所说的相反.)

解决方法:

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

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

void f(const std::string_view &);

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

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

标签:linkage,c,c11,language-lawyer,c17
来源: https://codeday.me/bug/20191001/1838254.html