2017-08-14 11 views
3

私は関係なく、彼らは何をすべきかの、そしてC++標準:ODRとconstexprのはstd :: string_view

#ifndef FOO_H_ 
#define FOO_H_ 

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

#endif // FOO_H_ 

が含まれている、それは単一のプログラムで複数の中から.ccファイルをfoo.hを含めても安全であるヘッダーfoo.hを持っている場合kSomeStringのシンボルを使用するか、ODR違反の原因となる可能性のある用途がありますか?

また、kSomeString.data().ccファイルに同じポインタを返すことが保証されていますか?

可能であれば、C++ standardの文言の具体的な言及を希望します。ありがとう!

+3

これは特に 'string_view'と具体的に何が関係していますか? –

+1

ほとんどの質問はヘッダ内の 'constexpr'宣言に関するものですが、初期化のためのC文字列の使用に関する特別な問題があります。 'constexpr int'です。 – jacobsa

答えて

6

複数の翻訳単位のfoo.hを含むだけでODRに違反しません。しかし、確かにODRに違反する可能性があるのはkSomeStringです。詳細と標準文言についてはこちらをご覧ください:https://stackoverflow.com/a/34446445

文字列リテラル"blah"は、すべての翻訳単位で同じオブジェクトであることが保証されていないためkSomeString.data()は、すべての翻訳単位で同じ値を返すことを保証するものではありません。 [lex.string]/16によれば、上記指定として与えられた文字の初期化静的記憶域期間を持つ文字列リテラルオブジェクトに文字列リテラル結果を評価

。すべての文字列リテラルが区別できる(重複しないオブジェクトに格納される)かどうか、文字列リテラルの連続した評価が同じか異なるオブジェクトをもたらすかどうかは指定されません。 [注:文字列リテラルを変更しようとすると、定義されません。 - エンドノート] C++ 17では

、電位ODR違反がinlineことがkSomeStringを定義することによって防止することができます。これにより、外部リンケージ、したがってプログラム全体で単一のアドレスが与えられ(および[basic.link]/4参照)、それを複数定義することができます([basic.def.odr]/4参照)。明らかに.data()は1つの可能な値だけを返すことができます。

+0

私の例では、 'kSomeString'のODRに問題のある用途があるのですか? [basic.link/3.2](http://eel.is/c++draft/basic.link#3.2)は、名前空間のスコープとconstなので、すべての翻訳単位で内部リンケージを保証しているようです。 – jacobsa

+0

(私自身の質問に答える:問題のある使用例を示す[この回答](https://stackoverflow.com/a/46107877/1505451)を参照してください)。 – jacobsa

関連する問題