【问题标题】:container of string_view's - are they always null-terminated? [duplicate]string_view 的容器 - 它们总是以空值结尾吗? [复制]
【发布时间】:2021-12-17 23:30:06
【问题描述】:

让我们给出任何包含std::string_view对象的数据结构:

std::vector<std::string_view> v{ "abc", "def" };
std::deque<std::string_view> d{ "abc", "def" };
std::set<std::string_view> s{ "abc", "def" };

cpp 标准是否保证这些容器存储类 std::string_view 的对象,这些对象指向以 null 结尾的字符串文字?

我的意思是这样写代码安全吗:

void foo(const char* ptr) {
    printf("%s", ptr);
}

for (auto elem : v)
    foo(elem.data());

for (auto elem : d)
    foo(elem.data());

for (auto elem : s)
    foo(elem.data());

【问题讨论】:

  • 你至少试过了吗?它会给你的问题增加更多的“重量”。因为你可以说“我试过了,看起来它有效,但我仍然不确定它是否正确和/或安全。”这比“这是一些我懒得自己运行的代码。可以吗?”
  • 在具有“未定义行为”概念的语言(如 C++)中,尝试并不是确定预期行为或代码正确性的好方法。 @sweenish
  • @CodyGray 我觉得你并没有真正阅读我的评论。
  • @sweenish 我没有得到 OP 没有尝试运行代码的印象。对我来说,“它是否由 cpp 标准保证”“它是否安全” 意味着他们尝试并获得了预期的行为。如果他们不尝试,他们可能只会问“那些 string_views 是否为空终止”,而没有提及标准。
  • 不,我不希望 C 或 C++ 程序员通过实验来学习。这会导致错误的代码和误解,这让我头疼不已。我宁愿他们查阅标准、值得信赖的参考资料,或者询问知道的人。

标签: c++ c++17 string-view


【解决方案1】:

是的,这是安全的。

一般std::string_views 不必以 null 结尾,但在这里您使用以 null 结尾的字符串显式初始化它们。

编译器不允许仅基于分配给string_view的事实从字符串中删除空终止符。

唯一允许这样做的情况是它不改变程序行为(as-if rule),这意味着您无需担心。

【讨论】:

  • 如果您从 std::string 构造 string_view,我是否纠正了这通常不起作用?
  • @SirGuy std::string 本身是空终止的,所以这也是安全的。 OTOH,您可以从string部分 构造string_view,那么就不会有空终止符。
  • @SirGuy 这取决于您是否包含字符串的结尾。如果您不尝试将字符串视图的数据作为char* 传递,它将忽略string_view 通常结束的位置,并实际结束后一个空终止符所在的位置。
  • @HolyBlackCat 根据this std::string 不保证包含空终止符,但是 std::string::c_str 的返回值包含。实现如何实现这一点可能意味着空终止符始终存在,但依赖它不会“由标准保证”
  • @SirGuy 将std::string 转换为std::string_view 时,std::string_view 是从std::string::data() 构造的,保证为空终止(C++11 起),然后它将只要std::string 的生命周期足够长就可以了。
猜你喜欢
  • 2011-06-29
  • 2020-02-15
  • 1970-01-01
  • 1970-01-01
  • 2010-10-01
  • 2015-05-20
  • 1970-01-01
  • 2011-08-29
  • 1970-01-01
相关资源
最近更新 更多