0

这是我的代码(虽然删除了一些不相关的部分):

#include <atomic>
#include <math.h>
#include <iostream>

using namespace std;

struct Profiler
{
private:
    Profiler() {}
    Profiler(const Profiler& other) {}
    Profiler operator = (const Profiler& other) { return *this; }

public:
    static atomic_ullong a;
    static atomic_ullong b;
};

atomic_ullong Profiler::a = { (unsigned long long)0 };
atomic_ullong Profiler::b = { (unsigned long long)0 };

bool func()
{
    Profiler::a++;
    float det = rand();

    if (abs(det) < numeric_limits<float>::epsilon())
        return false;

    Profiler::b++;

    return true;
}

int main(int argc, char** argv)
{
    bool result = func();

    cout << result << endl;

    system("pause");

    return 0;
}

它在调试模式下编译和运行良好。但是,在我切换到发布模式后,我在运行时不断收到访问冲突异常。如果我将 atomic_ullong 更改为 atomic_ulong 或 atomic_uint,它运行起来没有问题,这太奇怪了。但这两个的长度是不够的。所以有谁知道为什么会发生这种情况以及如何解决它?请帮忙!

4

1 回答 1

1

一个相当明显的错误代码生成案例。顶部有一个非常奇怪的序言func

push        ebx  
mov         ebx,esp  
sub         esp,8  
and         esp,0FFFFFFF8h  
add         esp,4  
push        ebp  
mov         ebp,dword ptr [ebx+4]  
mov         dword ptr [esp+4],ebp  
mov         ebp,esp  
sub         esp,18h  

不寻常,但不是一个直接的问题。问题出在结语中:

mov         esp,ebp  
pop         ebp  
mov         esp,ebx  
pop         ebx  
ret  

EBX在函数体中用作临时寄存器。此时它的值恰好是 1。所以 thenESP变成 1,然后POP尝试从中读取,显然是伪造的,地址

我建议您在http://connect.microsoft.com/visualstudio报告该问题。同时,作为一种直接的解决方法,如果您func使用#pragma optimize( "", off )#pragma optimize( "", on )

于 2013-09-15T13:57:19.463 回答