是否有可能保证在C++中没有优化代码执行内存写入?

sha*_*oth 28 c++ compiler-construction optimization compiler-optimization

允许C++编译器优化写入内存:

 {
     //all this code can be eliminated
     char buffer[size];
     std::fill_n( buffer, size, 0);
 }
Run Code Online (Sandbox Code Playgroud)

处理敏感数据时,典型方法是使用volatile*指针来确保编译器发出内存写入.以下是SecureZeroMemory()Visual C++运行时库中的函数实现方式(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;
}
Run Code Online (Sandbox Code Playgroud)

该函数将传递的指针强制转换为volatile*指针,然后通过后者写入.但是,如果我在局部变量上使用它:

char buffer[size];
SecureZeroMemory( buffer, size );
Run Code Online (Sandbox Code Playgroud)

变量本身不是volatile.因此根据C++标准定义的可观察行为写入buffer不计入可观察行为,看起来它可以被优化掉.

现在有很多关于页面文件,缓存等的评论都是有效的,但是我们在这个问题中忽略它们.这个问题唯一的问题是存储器写入的代码是否被优化掉了.

是否有可能确保在C++中没有优化写入内存的代码?该解决方案SecureZeroMemory()是否符合C++标准?

Dav*_*rtz 8

没有便携式解决方案.如果它想要,编译器可以在你在内存中的多个位置使用它时制作数据的副本,并且任何零函数都可以将它当时只使用它的零.任何解决方案都是不可移植的.