FYI: Visual Studio 2012 /O2 compiler bug

I filled this VS 2012 C++ compiler bug with Microsoft Connect today. I also wanted to post it here to help people having weird issues when migrating to Visual Studio 2012.

It's not present before VS 2012.

Also, maybe someone can try it with Visual Studio 2013 and post the results.

Important: this is a /O2 (Release) only issue. So if you have a weird bug in VS2012 Release but not in Debug, read the code below.

Thanks,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// Two implementations of f(p) = 2 p.x - 1 
// They should give the same output, but with all versions of 
// Visual Studio 2012 C++ compiler up to Update 4 RC  in release, 
// i.e. /O2 switch, version A gives the wrong output
// A:      1       B:      1
// A:      1       B:      3
// A:      5       B:      5
// A:      3       B:      7
// A:      9       B:      9
// A:      5       B:      11
// A:      13      B:      13
// A:      7       B:      15
// A:      17      B:      17
// A:      9       B:      19
// Press any key to continue . . .
#include <iostream>

namespace
{
    const int NELEMENTS = 10;

    class Bar
    {
    public:
        Bar()
        :m_x(0.0)
        {
        }

        double m_x;
        double m_other; // without the other no bug
    };

    void foo_version_A( Bar *pts, int n )
    {
        for (int i = 0; i < n; ++i)
        {
           pts[i].m_x *= 2.0;
           pts[i].m_x -= 1.0;
        }
    }

    void foo_version_B( Bar *pts, int n )
    {
        for (int i = 0; i < n; ++i)
        {
           pts[i].m_x = 2.0 * pts[i].m_x - 1.0;
        }
    }
}

int main(void)
{
    Bar dataA[NELEMENTS];
    Bar dataB[NELEMENTS];
    
    for (int i = 0; i < NELEMENTS; ++i)
    {
        dataA[i].m_x = i + 1.0;
        dataB[i].m_x = i + 1.0;
    }

    foo_version_A( dataA, NELEMENTS );
    foo_version_B( dataB, NELEMENTS );
    
    for (int i = 0; i < NELEMENTS; ++i)
    {
        std::cout << "A:\t" << dataA[i].m_x << "\tB:\t" << dataB[i].m_x << std::endl;
    }
}
Microsoft VS team decided not to fix the compiler bug in VS 2012, although they have known about this issue for nearly a year.

Older report:

http://connect.microsoft.com/VisualStudio/feedback/details/774941/problem-with-compiler-optimization

My report:

http://connect.microsoft.com/VisualStudio/feedback/details/805849/c-o2-compiler-bug

It's supposed to be fixed in VS 2013.

Seemed pretty major from my point of view. I lost a full day finding this issue in a medium-sized project. It could have been much worst in a large codebase.
Topic archived. No new replies allowed.