C++ C++;标准:ODR和constepr std::string\u视图

C++ C++;标准:ODR和constepr std::string\u视图,c++,language-lawyer,c++17,linkage,one-definition-rule,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_ 那么,在单个程序中从多个.cc文件中包含foo.h是否安全,而不管它们对符号kSomeString做了什么,或者是否存在可能导致ODR冲突的某些使用 另外,是否保证kSomeString.data()将在.cc文件中返回相同的

如果我有一个标题
foo.h
,其中包含

#ifndef FOO_H_
#define FOO_H_

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

#endif  // FOO_H_
那么,在单个程序中从多个
.cc
文件中包含
foo.h
是否安全,而不管它们对符号
kSomeString
做了什么,或者是否存在可能导致ODR冲突的某些使用

另外,是否保证
kSomeString.data()
将在
.cc
文件中返回相同的指针


如果可能的话,我想具体提及合同中的措辞。谢谢

仅包括来自多个翻译单元的
foo.h
,不会违反ODR。然而,实际上,
kSomeString
的某些用法会违反ODR。有关详细信息和标准措辞,请参见此处:

不能保证
kSomeString.data()
在所有翻译单位中返回相同的值,因为不能保证字符串文字
“blah”
在所有翻译单位中都是相同的对象。根据,

计算字符串文字将生成一个具有静态存储持续时间的字符串文字对象,该对象根据上面指定的给定字符初始化。是否所有字符串文字都是不同的(即,存储在非重叠对象中),以及字符串文字的连续求值是否产生相同或不同的对象都未指定。[ 注意:试图修改字符串文字的效果未定义- 尾注 ]


在C++17中,通过将
kSomeString
定义为
inline
,可以防止潜在的ODR冲突。这将为它提供外部链接,从而在整个程序中提供一个地址(请参见和),并允许它被多次定义(请参见)。显然
.data()
然后只能返回一个可能的值。

这与
string\u view
具体有什么关系?大多数问题通常是关于头中的
constepr
声明,但是在使用C字符串进行初始化时可能会遇到一些特殊问题,例如
constepr int
。您确定在我的示例中,
kSomeString
的ODR使用存在一些问题吗?似乎可以保证它在所有转换单元中都有内部链接,因为它是命名空间范围和常量。(要回答我自己的问题,请参阅,它给出了一个有问题的使用示例。)