C ++标准:ODR和constexpr std :: string_view [英] C++ standard: ODR and constexpr std::string_view
问题描述
如果我的标题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
个文件中返回相同的指针吗?
如果可能的话,我想具体引用 C ++标准中的措词.谢谢!
仅包含多个翻译单元中的foo.h
不会违反ODR.但是,实际上,kSomeString
的某些用法会违反ODR.有关详细信息和标准措辞,请参见此处: https://stackoverflow.com/a/34446445
不能保证kSomeString.data()
在所有转换单元中都将返回相同的值,因为不能保证字符串文字"blah"
在所有转换单元中均是相同的对象.根据 [lex.string]/16 ,
对 string-literal 求值将生成具有静态存储期限的字符串文字对象,该对象将从上面指定的给定字符初始化.所有字符串文字是否都不同(即存储在不重叠的对象中),以及字符串字面量的连续求值是否得出相同或不同的对象,都不确定. [注意:尝试修改字符串文字的效果是不确定的. —注释]
在C ++ 17中,可以通过将kSomeString
定义为inline
来防止潜在的ODR违规.这将使它具有外部链接,因此在整个程序中都只有一个地址(请参阅 [basic.link ]/3 和 [basic.link]/4 )并允许对其进行多重定义(请参见 [basic.def.odr]/4 ).显然.data()
然后只能返回一个可能的值.
If I have a header foo.h
which contains
#ifndef FOO_H_
#define FOO_H_
namespace foo {
constexpr std::string_view kSomeString = "blah";
}
#endif // FOO_H_
then is it safe to include foo.h
from within multiple .cc
files in a single program, regardless of what they do with the symbol kSomeString
, or are there some uses that could cause an ODR violation?
Also, is it guaranteed that kSomeString.data()
will return the same pointer across .cc
files?
I'd like specific references to wording in the C++ standard if possible. Thanks!
Merely including foo.h
from multiple translation units will not violate the ODR. However, indeed, there are some uses of kSomeString
that will violate the ODR. See here for details and standard wording: https://stackoverflow.com/a/34446445
It is not guaranteed that kSomeString.data()
will return the same value in all translation units because it is not guaranteed that the string literal "blah"
is the same object in all translation units. According to [lex.string]/16,
Evaluating a string-literal results in a string literal object with static storage duration, initialized from the given characters as specified above. Whether all string literals are distinct (that is, are stored in nonoverlapping objects) and whether successive evaluations of a string-literal yield the same or a different object is unspecified. [ Note: The effect of attempting to modify a string literal is undefined. — end note ]
In C++17, the potential ODR violations can be prevented by defining kSomeString
to be inline
. This will give it external linkage and hence a single address throughout the program (see [basic.link]/3 and [basic.link]/4) and allow it to be multiply defined (see [basic.def.odr]/4). Obviously .data()
can then only return one possible value.
这篇关于C ++标准:ODR和constexpr std :: string_view的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!