Question

This is my code(removed some unreleated parts though):

#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;
}

It compiles and runs well under debug mode. However, after I switch to release mode, I keep getting access violation exceptions when it runs. It's so weird that it runs without a problem if I change atomic_ullong to atomic_ulong or atomic_uint. But the length of those two is just not enough. So anyone know why this is happening and how to solve it? Please help!

Was it helpful?

Solution

A rather clear case of bad code generation. There's a pretty weird prolog at the top of 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  

Unusual, but isn't an immediate problem. The problem is in the epilog:

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

EBX is used as a scratch register in the body of the function. Its value happens to be 1 by this point. So then ESP becomes 1, and then POP tries to read from that, obviously bogus, address

I suggest you report the issue at http://connect.microsoft.com/visualstudio. Meanwhile, as an immediate workaround, it works if you surround func with #pragma optimize( "", off ) and #pragma optimize( "", on )

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top