c++之`string.assign(string.data(), 5)` 是明确定义还是 UB

zhenyulu 阅读:16 2024-11-24 20:56:43 评论:0

一位同事想写这个:

std::string_view strip_whitespace(std::string_view sv); 
 
std::string line = "hello  "; 
line = strip_whitespace(line); 

我说返回 string_view先验让我感到不安,此外,这里的混叠对我来说看起来像 UB。

我可以肯定地说 line = strip_whitespace(line)在这种情况下相当于 line = std::string_view(line.data(), 5) .我相信会调用 string::operator=(const T&) [with T=string_view] , 定义为等价于 line.assign(const T&) [with T=string_view] , 定义为等价于 line.assign(line.data(), 5) ,它被定义为:
Preconditions: [s, s + n) is a valid range. 
Effects: Replaces the string controlled by *this with a copy of the range [s, s + n). 
Returns: *this. 

但这并没有说明出现混叠时会发生什么。

我昨天在 cpplang Slack 上问了这个问题,得到的答案好坏参半。在这里寻找 super 权威的答案,和/或对真实库供应商实现的实证分析。

I wrote test cases对于 string::assign , vector::assign , deque::assign , list::assign , 和 forward_list::assign .
  • Libc++ 使所有这些测试用例都能工作。
  • 除了 forward_list 之外,Libstdc++ 使它们都可以工作。 ,这是段错误。
  • 我不知道 MSVC 的库。

  • libstdc++ 中的段错误让我希望这是 UB;但我也看到 libc++ 和 libstdc++ 至少在常见情况下会付出很大的努力来完成这项工作。

    请您参考如下方法:

    除非有几个你的异常(exception),否则在字符串 invalidates 上调用非常量成员函数(即 assign ) [...] 指针 [...] 指向它的元素。这违反了 preconditionassign[s, s + n)是一个有效范围,所以这是未定义的行为。

    请注意 string::operator=(string const&)具有专门用于使自我分配成为无操作的语言。


    标签:C++
    声明

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    关注我们

    一个IT知识分享的公众号