问题描述
C ++编译器允许:
C++ compilers are allowed to optimize away writes into memory:
{
//all this code can be eliminated
char buffer[size];
std::fill_n( buffer, size, 0);
}
当处理敏感数据时,典型的方法是使用 volatile *
指针,以确保编译器发出内存写入。下面是如何在Visual C ++运行时库中实现 SecureZeroMemory()
的功能(WinNT.h):
When dealing with sensitive data the typical approach is using volatile*
pointers to ensure that memory writes are emitted by the compiler. Here's how SecureZeroMemory()
function in Visual C++ runtime library is implemented (WinNT.h):
FORCEINLINE PVOID RtlSecureZeroMemory(
__in_bcount(cnt) PVOID ptr, __in SIZE_T cnt )
{
volatile char *vptr = (volatile char *)ptr;
#if defined(_M_AMD64)
__stosb((PBYTE )((DWORD64)vptr), 0, cnt);
#else
while (cnt) {
*vptr = 0;
vptr++;
cnt--;
}
#endif
return ptr;
}
函数将传递的指针转换为 volatile *
指针,然后通过后者写入。但是如果我使用它在一个局部变量:
The function casts the passed pointer to a volatile*
pointer and then writes through the latter. However if I use it on a local variable:
char buffer[size];
SecureZeroMemory( buffer, size );
变量本身不是 volatile
。所以根据C ++标准定义的可观察行为写入 buffer
不算作可观察的行为,看起来像可以优化掉。
the variable itself is not volatile
. So according to C++ Standard definition of observable behavior writes into buffer
don't count as observable behavior and looks like it can be optimized away.
现在有很多关于页面文件,缓存等的评论,这些都是有效的,但让我们在这个问题中忽略它们。这个问题的唯一问题是内存写入的代码是否被优化掉了。
Now there're a lot of comments below about page files, caches, etc, which are all valid, but let's just ignore them in this question. The only thing this question is about is whether the code for memory writes is optimized away or not.
可以确保写入内存的代码不会被优化掉在C ++?解决方案是否在 SecureZeroMemory()
符合C ++标准?
Is it possible to ensure that code doing writes into memory is not optimized away in C++? Is the solution in SecureZeroMemory()
compliant to C++ Standard?
推荐答案
没有可移植的解决方案。如果它想要,编译器可以已经制作了数据的副本,而你在内存中的多个地方使用它,任何零函数可能只有它当时使用的一个零。任何解决方案都将是非便携式的。
There is no portable solution. If it wants to, the compiler could have made copies of the data while you were using it in multiple places in memory and any zero function could zero only the one it's using at that time. Any solution will be non-portable.
这篇关于是否有可能保证代码做内存写入没有优化在C ++?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!