Rei*_*kin 7 c++ language-lawyer
作为此问题的后续部分,我正在想象一个存储敏感数据(如加密密钥)的类。为简化起见,假设不涉及继承。
struct Credential {
std::array<uint8_t, 32> secretStuff;
~Credential() { memset_s(secretStuff.data(), 32, 0, 32); }
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试确定是否可以保证运行此类型的对象的析构函数,或者是否需要做一些花哨的事情,例如使用分配器以确保擦除内存。我对抵御编译器优化的适应性很感兴趣,因此我正在寻找标准的章节,以确保无论如何我都会得到正确的行为。
在前面的问题中,已经确定static保证自动分配和存储中的对象可以运行其析构函数。我对static此案不感兴趣;就我而言,确保程序终止后,先前使用的内存内容不会泄漏是操作系统的职责。对于程序员故意破坏事物的情况,我也不感兴趣...毕竟,没有什么可说的是他们不能只复制数据。
假设您是一名编译器作者,并且想在遵守标准的同时打破它。您有什么办法可以避免调用析构函数(程序终止除外)?也许一些奇怪的异常处理行为?如果不允许您这样做,为什么不这样做呢?
这里涉及两个问题。一是效果明显。析构函数被允许具有可观察的效果,当它们这样做时,这是一个硬保证。析构函数可以将数据刷新到文件中,如果析构函数不运行,这些数据就会丢失。析构函数可以释放裸指针引用的对象,如果析构函数不运行,这些对象就会泄漏。析构函数与其他函数一样重要,并且它们可见的副作用不会神奇地消失。
然而,如果您担心不可观察的影响,那么所有的赌注都将落空。编译器可以证明对兼容程序没有明显影响的任何内容都可以被优化掉。这就是为什么我们有memset_s,除非你只使用定义所有你想要依赖的可观察效果的函数,否则所有的赌注都会被取消。