BUG: Bad Codegen with /Og and FP Mult in Class with Virt Dtor

Last reviewed: September 16, 1997
Article ID: Q170514
The information in this article applies to:
  • The C/C++ Compiler (CL.EXE) included 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 /Op.

-or-

Do not use /Og. Note that /O1, /O2, and /Ox are aggregate optimization switches that include /Og.

-or-

Use the optimize pragma around the class member to disable the /Og optimization or to turn on the /Op optimization.

-or-

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. We are researching this bug and will post new information here in the Microsoft Knowledge Base as it becomes available.

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
Keywords          : CLIss CodeGen vcbuglist500
Version           : 5.0
Platform          : NT WINDOWS
Issue type        : kbbug


================================================================================


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: September 16, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.