C ++标准:ODR和constexpr std :: string_view [英] C++ standard: ODR and constexpr std::string_view

查看:132
本文介绍了C ++标准:ODR和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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆