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