[英]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.