C ++标准:ODR和constexpr std :: string_view

时间:2017-08-14 00:28:21

标签: c++ language-lawyer c++17 linkage one-definition-rule

如果我有一个包含

的标题foo.h
#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中特别提及措辞。谢谢!

1 个答案:

答案 0 :(得分:7)

仅包括来自多个翻译单元的foo.h不会违反ODR。但是,确实有kSomeString的某些用法会违反ODR。有关详细信息和标准措辞,请参阅此处:https://stackoverflow.com/a/34446445

无法保证kSomeString.data()将在所有翻译单元中返回相同的值,因为无法保证字符串文字"blah"在所有翻译单元中都是同一个对象。根据{{​​3}},

  

评估 string-literal 会产生一个具有静态存储持续时间的字符串文字对象,从上面指定的给定字符初始化。是否所有字符串文字都是不同的(即,存储在非重叠对象中)以及是否对字符串文字的连续评估产生相同或不同的对象是未指定的。 [注意:尝试修改字符串文字的效果未定义。 - 结束记录]

在C ++ 17中,通过将kSomeString定义为inline,可以防止潜在的ODR违规。这将为其提供外部链接,从而在整个计划中提供单个地址(请参阅[lex.string]/16[basic.link]/3)并允许对其进行多重定义(请参阅[basic.link]/4)。显然.data()只能返回一个可能的值。