【问题标题】:Thread safety of std::string::c_str()std::string::c_str() 的线程安全
【发布时间】:2023-01-11 03:30:52
【问题描述】:

在我看来,现代 C++ 似乎要求在调用运算符、c_str() 或 data() 之后,保证字符串的内容以 null 终止。

但是,这个初始化有没有可能“懒惰地”完成?也就是说,在调用其中一个函数之前,为字符串的内容分配的缓冲区可能不会以 null 终止,这可能会使该函数的使用不是 thread_safe?理想情况下,我正在以某种方式从标准中寻找特定的引文。

【问题讨论】:

  • 所有const 限定的成员函数在标准库中都是线程安全的。
  • 如果不先调用c_str(),您如何获得指向此内容的指针?
  • 我认为 NathanOliver 提到的参考是 eel.is/c++draft/res.on.data.races#3 ,但是 data() 有一个非常量重载,所以不确定整个标准律师的答案到底是什么。
  • @Mat 但仍然可以调用 const 版本并获取以 null 结尾的字符串。所以非常量 data() 会以某种方式修改它是荒谬的。非常量版本只是返回一个非常量指针,因此用户可以对其进行编辑。

标签: c++ c++11 thread-safety stdstring


【解决方案1】:

这就是 std::string 直到 C++11 之前的方式,又名“现代 C++”。这些字符串是通过写时复制延迟初始化的。然而,标准要求 c_str() 具有严格的性能要求,这使得初始化被推入构造函数。移动语义部分缓解了性能损失,但这就是今天的现状。

如果没有明确标记,我认为任何 STL 函数都不是线程安全的。使所有方法都是线程安全的将非常昂贵。

【讨论】:

  • 请注意,STL 和标准库是两个不同的东西。 AFAIK STL 甚至不知道线程是什么。另请参阅 this 关于通用线程安全保证。
  • 我相信“线程安全”意味着可以从不同的线程调用这些方法而不会导致数据竞争。通常,const 方法承诺这一点。那是“只读”方法。
  • @NathanOliver STL 从一开始就是 C++ 标准的一部分。这实际上是我最大的不满之一——我认为不应该。 eel.is/c++draft/#strings
  • 小点:字符串可能延迟初始化;这不是必需的,大多数实现都没有这样做。
  • @PeteBecker 是的,我们有点像整个世界一样使用 GCC,而忘记了那里还有其他编译器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-10
相关资源
最近更新 更多