[英]How to safely compare std::complex<double> with Zero with some precision Epsilon?
[英]How to safely zero std::array?
我正在尝试将 class 析构函数中的std::array
安全归零。 从safe开始,我的意思是我想确保编译器永远不会优化这个归零。 这是我带来的:
template<size_t SZ>
struct Buf {
~Buf() {
auto ptr = static_cast<volatile uint8_t*>(buf_.data());
std::fill(ptr, ptr + buf_.size(), 0);
}
std::array<uint8_t, SZ> buf_{};
};
此代码是否按预期工作? 在任何情况下,该volatile
关键字都会阻止编译器进行优化吗?
C++ 标准本身并没有做出明确的保证。 它说:
通过 volatile 泛左值访问的语义是实现定义的。 ...
[注 5: volatile 是对实现的提示,以避免涉及 object 的激进优化,因为 object 的值可能会通过实现无法检测到的方式进行更改。 此外,对于某些实现,易失性可能表明需要特殊的硬件指令才能访问 object。 有关详细语义,请参见 [intro.execution]。 通常,在 C++ 中,volatile 的语义与在 C 中的语义相同。 ——尾注]
Despite the lack of guarantees by the C++ standard, over-writing the memory through a pointer to volatile is one way that some crypto libraries clear memory - at least as a fallback when system specific function isn't available.
PS我建议改用const_cast
,以避免意外转换为不同的类型,而不是不同的限定相同类型:
auto ptr = const_cast<volatile std::uint8_t*>(buf_.data());
隐式转换也有效:
volatile std::uint8_t* ptr = buf_.data();
用于此目的的系统特定函数是SecureZeroMemory
中的 SecureZeroMemory 和一些 BSD 和 glibc 中的explicit_bzero
_bzero。
C11 标准有一个可选的 function memset_s
用于此目的,它也可能在 C++ 中可供您使用,但当然不能保证可用。
有一个提案P1315将类似的 function 引入 C++ 标准。
一种选择是使用std::atomic_ref
进行宽松的原子存储,编译器无法省略。 C++20 示例:
#include <cstdint>
#include <atomic>
#include <array>
template<class Array>
void clear(Array& a) {
for(auto& e : a)
std::atomic_ref{e}.store(0, std::memory_order_relaxed);
}
void f(std::array<uint32_t, 32>& a) {
clear(a);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.