2017-08-14 128 views
3

如果我有一个头foo.h包含C++标准:ODR和constexpr的std :: string_view

#ifndef FOO_H_ 
#define FOO_H_ 

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

#endif // FOO_H_ 

则是安全的从多个中包括foo.h在一个程序中.cc文件,无论他们做什么符号为kSomeString,还是有一些可能导致ODR违规的用途?

此外,它是否保证kSomeString.data()将返回相同的指针跨越.cc文件?

如果可能,我想特别提及C++ standard中的措词。谢谢!

+3

这与'string_view'具体有什么关系? –

+1

大部分问题都是关于头文件中的'constexpr'声明,但是可能会有一些特殊的问题围绕使用C字符串进行初始化而不适用于'constexpr int'。 – jacobsa

回答

6

仅包括来自多个翻译单元的foo.h不会违反ODR。但是,确实有一些使用kSomeString会违反ODR。在这里看到的细节和标准的写法:https://stackoverflow.com/a/34446445

它不能保证kSomeString.data()将在所有的翻译单位返回相同的值,因为它不能保证该字符串字面"blah"是在所有的翻译单位相同的对象。据[lex.string]/16

评估字串文本导致具有静态存储持续时间的字符串文字对象,如上述规定的从给定的字符初始化。是否所有字符串文字都是不同的(即,是否存储在非重叠对象中),以及是否对字符串文字的连续求值产生相同或不同的对象是未指定的。 [注意:尝试修改字符串文字的效果未定义。 - 注完]

在C++ 17,潜在的ODR违规可以通过定义kSomeStringinline防止。这将给它外部链接,因此在整个程序中有一个地址(见[basic.link]/3[basic.link]/4),并允许它被多次定义(见[basic.def.odr]/4)。显然.data()可以只返回一个可能的值。

+0

在我的例子中,你确定'kSomeString'有一些ODR有问题的用法吗?看起来像[basic.link/3.2](http://eel.is/c++draft/basic.link#3.2)保证它将在所有翻译单元中具有内部链接,因为它是名称空间作用域和常量。 – jacobsa

+0

(回答我自己的问题:请参阅[本答案](https://stackoverflow.com/a/46107877/1505451),它给出了一个有问题的使用示例。) – jacobsa

相关问题