2017-08-14 124 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

相關問題