使用 `const_cast<char*>()` 将 `std::string::c_str()` 的结果传递给 `mkdtemp()`

Passing the results of `std::string::c_str()` to `mkdtemp()` using `const_cast<char*>()`

好的,所以:我们都知道,通常在任何地方使用 const_cast<>() 都是非常糟糕的,这实际上是一种编程 war 犯罪。所以这是一个关于在特定情况下它可能有多糟糕的假设性问题。

也就是说:我 运行 浏览了一些代码,做了这样的事情:

std::string temporary = "/tmp/directory-XXXXX";
const char* dtemp = ::mkdtemp(const_cast<char*>(temporary.c_str()));
/// `temporary` is unused hereafter

…现在,我已经 运行 跨越许多关于如何获得对 std::string 实例的底层缓冲区的可写访问权限的描述(例如 q.v。 ) – 所有这些都有一个警告,是的,这些方法不保证运行符合任何 C++ 标准,但实际上它们都可以。

考虑到这一点,我只是好奇使用 const_cast<char*>(string.c_str()) 与其他已知方法(例如前面提到的 &string[0], &c)相比如何……我问是因为我在其中找到这个的代码使用的方法在实践中似乎工作得很好,我想在我尝试不可避免的 const_cast<>()-free 重写之前先看看专家的想法。

  • const 无法在硬件级别强制执行,因为在实践中,在非假设环境中,您只能将只读属性设置为完整的 4K 内存页面并且存在大页面在途中,这大大减少了 CPU 在 TLB.

  • 中的查找未命中率
  • const 不会像 C99 中的 __restrict 那样影响代码生成。其实const,粗略的说就是"poison all write attempts to this data, I'd like to protect my invariants here"

由于std::string是一个可变字符串,它的底层缓冲区不能分配在只读内存中。因此 const_cast<> 不应导致程序崩溃,除非您要更改底层缓冲区边界之外的某些字节或尝试 deletefree()realloc() 某些内容。但是,更改缓冲区中的字符可能会被 class 确定为不变违规。因为在那之后您不使用 std::string 实例而只是将其丢弃,所以这不会引起程序崩溃,除非某些特定的 std::string 实现决定在销毁之前检查其不变量的完整性并在某些情况下强制崩溃这些都坏了。因为这样的检查不能在少于 O(N) 的时间内完成,并且 std::string 是一个性能关键 class,所以任何人都不可能完成。

另一个问题可能来自Copy-on-Write策略。因此,通过直接修改缓冲区,您可能会破坏与您的字符串共享缓冲区的其他 std::string 实例。但几年前,大多数 C++ 专家得出结论,COW 太脆弱且太慢,尤其是在多线程环境中,因此现代 C++ 库不应该使用它,而是坚持尽可能使用移动构造并避免堆流量小适用的长度字符串。