相关疑难解决方法(0)

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

允许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++标准?

c++ compiler-construction optimization compiler-optimization

28
推荐指数
1
解决办法
1493
查看次数

强制读取volatile变量

我正在处理的嵌入式项目需要读取内存中的特定位置,但不需要该内存位置的值.目前我正在将volatile变量读入虚拟变量,foo1()如下所示,但我很好奇这个方法foo2().

void foo1(void) {
    volatile uint32_t *a = (volatile uint32_t *)0xdeadbeef;
    volatile uint32_t discard = *a;
}
void foo2(void) {
    volatile uint32_t *a = (volatile uint32_t *)0xdeadbeef;
    *a;
}
Run Code Online (Sandbox Code Playgroud)

请参阅dissassembly(使用gcc 4.7.2和-O3编译):

  foo1:
movl      0xdeadbeef, %eax
movl      %eax, -0x4(%rsp)
ret
  foo2:
movl      0xdeadbeef, %eax
ret
Run Code Online (Sandbox Code Playgroud)

该方法foo2()似乎工作,但我想知道它是否可以保证工作,并不是我正在使用的编译器版本和优化的副作用.

c language-lawyer

6
推荐指数
1
解决办法
2381
查看次数