FIX: Bad Codegen with /Og and Floating-Point Multiplication Class with Virtual Destructor
ID: Q170514
|
The information in this article applies to:
-
The C/C++ Compiler (CL.EXE), used with:
-
Microsoft Visual C++, 32-bit Editions, version 5.0
SYMPTOMS
The Visual C++ 5.0 compiler may generate incorrect instructions when it
encounters floating-point multiplication in a member of a class that has a
virtual destructor.
RESOLUTION
Use one of the following four workarounds:
- Use /Op.
- Do not use /Og. Note that /O1, /O2, and /Ox are aggregate optimization
switches that include /Og.
- Use the optimize pragma around the class member to disable the /Og
optimization or to turn on the /Op optimization.
- Make the destructor non-virtual. This may not be an option if the given
class is derived from a class that has a virtual destructor in a library
that you cannot change.
STATUS
Microsoft has confirmed this to be a bug in the Microsoft products listed
at the beginning of this article. This problem was corrected in Visual C++ 5.0sp3.
MORE INFORMATION
Steps to Reproduce Behavior
// Compile options needed to reproduce the bug: /Og
// Compile options needed to work around the bug: /Og /Op
#include <stdio.h>
#include <math.h>
struct A {
double m_X;
double m_Y;
};
typedef double rg23[2][3];
struct B
{
rg23 m;
B(double rotn = 0);
void func(double *px, double *py) const;
virtual ~B(){}
};
B::B(double rotn)
{
double cosa = cos(rotn);
double sina = sin(rotn);
m[0][0] =
m[1][1] = cosa;
m[0][1] = -sina;
m[1][0] = sina;
m[0][2] =
m[1][2] = 0;
}
void B::func(double *px, double *py) const
{
double x = *px;
double y = *py;
*px = x * m[0][0] + y * m[0][1] + m[0][2];
*py = x * m[1][0] + y * m[1][1] + m[1][2];
}
int main () {
A a;
a.m_X=1.0;
a.m_Y=2.0;
printf("Values in: x=%lf; y=%lf\n", a.m_X, a.m_Y);
B ct;
ct.func(&a.m_X, &a.m_Y);
printf("Values out: x=%lf; y=%lf\n", a.m_X, a.m_Y);
return 0;
}
Expected Output
Values in: x=1.000000; y=2.000000
Values out: x=1.000000; y=2.000000
Actual Output
Values in: x=1.000000; y=2.000000
Values out: x=1.000000; y=0.000000
Additional query words:
Keywords : kbcode kbVC500bug kbVC600fix
Version : winnt:5.0
Platform : winnt
Issue type : kbbug