作为后续这个问题 https://stackoverflow.com/questions/57515813,我正在想象一个存储敏感数据(例如加密密钥)的类。为了简化事情,假设不涉及继承。
struct Credential {
std::array<uint8_t, 32> secretStuff;
~Credential() { memset_s(secretStuff.data(), 32, 0, 32); }
}
我正在尝试确定是否保证这种类型的对象运行其析构函数,或者我是否需要执行某些操作fancy https://stackoverflow.com/questions/57487566就像使用分配器来确保内存被擦除一样。我对编译器优化的弹性很感兴趣,所以我正在寻找标准中的章节和章节,以确保我无论如何都会得到正确的行为。
在前面的问题中,已经确定对象是自动分配和static
存储保证其析构函数运行。我对此不感兴趣static
案件;就我而言,操作系统的工作是确保程序终止后以前使用的内存的内容不会泄漏。我对程序员故意破坏事物的情况也不感兴趣……毕竟,没有什么可说的,他们不能一开始就把数据复制出来。
想象一下,您是一名编译器作者,想要在遵守标准的同时打破这一点。有什么办法可以避免调用析构函数(程序终止除外)?也许有一些奇怪的异常处理行为?如果你不被允许这样做,为什么不呢?
这里涉及两个问题。一是效果明显。析构函数被允许具有可观察的效果,当它们这样做时,这是一个硬保证。析构函数可以将数据刷新到文件中,如果析构函数不运行,这些数据就会丢失。析构函数可以释放裸指针引用的对象,如果析构函数不运行,这些对象就会泄漏。析构函数与其他函数一样重要,并且它们可见的副作用不会神奇地消失。
然而,如果您担心不可观察的影响,那么所有的赌注都将落空。编译器可以证明对兼容程序没有明显影响的任何内容都可以被优化掉。这就是为什么我们有memset_s
除非您只使用定义所有您想要依赖的可观察效果的函数,否则所有的赌注都会失败。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)