好吧,所以:我们都知道,通常在任何地方使用const_cast<>()
都很糟糕,这实际上是一种编程战争罪。因此,这是一个关于在特定情况下可能有多糟糕的假设问题。
也就是说:我遇到了一些代码,它做了这样的事情:
std::string temporary = "/tmp/directory-XXXXX";
const char* dtemp = ::mkdtemp(const_cast<char*>(temporary.c_str()));
/// `temporary` is unused hereafter
……现在,我已经看到了许多关于如何对std::string
实例的底层缓冲区进行可写访问的描述(q.v。https://stackoverflow.com/a/15863513/298171例如)–所有这些方法都有一个警告,是的,这些方法不能保证任何C++标准都能工作,但在实践中它们都能工作。
考虑到这一点,我只是想知道使用const_cast<char*>(string.c_str())
与其他已知方法(例如前面提到的&string[0]
,&c)相比如何……我之所以这么问,是因为我发现使用这种方法的代码在实践中似乎运行良好,我想在尝试不可避免的无const_cast<>()
重写之前,我会看看专家们的想法。
-
const
不能在硬件级别强制执行,因为在实践中,在非假设环境中,您可以仅将只读属性设置为完整的4K内存页,并且有大量页面正在进行中,这大大减少了CPU在TLB中的查找未命中。 -
const
不会像C99中的__restrict
那样影响代码生成。事实上,const
,粗略地说,意思是"毒害所有对此数据的写入尝试,我想在这里保护我的不变量"
由于std::string
是一个可变字符串,其底层缓冲区不能在只读内存中分配。所以const_cast<>
不应该导致程序崩溃,除非您要更改一些超出底层缓冲区界限的字节,或者尝试delete
、free()
或realloc()
之类的字节。然而,改变缓冲区中的字符可能被归类为不变违反。因为在那之后不使用std::string
实例,只需将其丢弃,所以这不应该引发程序崩溃,除非某个特定的std::string
实现决定在销毁之前检查其不变量的完整性,并在其中一些不变量损坏时强制崩溃。因为这样的检查不可能在小于O(N)的时间内完成,而且std::string
是性能关键类,所以任何人都不太可能完成。
另一个问题可能来自写时复制策略。因此,通过直接修改缓冲区,您可以破坏与您的字符串共享缓冲区的其他std::string
的实例。但几年前,大多数C++专家得出结论,COW太脆弱、太慢,尤其是在多线程环境中,所以现代C++库不应该使用它,而是坚持在可能的情况下使用移动构造,并在适用的情况下避免小长度字符串的堆流量。