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

时间:2015-12-07 05:25:18

标签: c++ stdstring mutable c-strings const-cast

好的,所以:我们都知道,const_cast<>()在任何地方使用都是如此糟糕,实际上是编程战争罪。所以这是一个假设的问题,关于在特定情况下可能有多么糟糕

即便:我遇到了一些类似的代码:

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

...现在,我遇到了很多关于如何获得std::string实例的底层缓冲区(例如qv https://stackoverflow.com/a/15863513/298171)的可写访问权限的描述 - 所有这些都有一个警告,是的,这些方法不能保证适用于任何C ++标准,但实际上它们都可以。

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

1 个答案:

答案 0 :(得分:3)

  • const无法在硬件级别强制执行,因为在实践中,在非假设环境中,您可以将只读属性设置为完整的4K内存页面,并且路上有大页面,这大大减少了TLB中的CPU查找失误。

  • const不会影响C99中__restrict的代码生成。实际上,const,粗略地说,意味着“毒害所有对这些数据的写入尝试,我想在这里保护我的不变量”

由于std::string是一个可变字符串,因此无法在只读内存中分配其底层缓冲区。所以const_cast<>不应该导致程序崩溃,除非您要更改底层缓冲区边界之外的某些字节或尝试deletefree()realloc()。但是,缓冲区中的字符变化可能被归类为不变违规。因为之后你没有使用std::string实例而只是把它扔掉,这不应该引起程序崩溃,除非某些特定的std::string实现决定在破坏之前检查其不变量的完整性并强制崩溃这些都破了。因为这种检查不能在O(N)时间内完成,而std::string是一个性能关键级别,所以不太可能由任何人完成。

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