BUG: Static Object No Longer Static When Optimized

Last reviewed: July 22, 1997
Article ID: Q119328
1.00 1.50 WINDOWS kbprg kbbuglist

The information in this article applies to:

  • Microsoft C/C++ Compiler (CL.EXE) included with Microsoft Visual C++ for Windows, versions 1.0 and 1.5

SYMPTOMS

When a static member function with a local static object is called from two different object modules, two different objects are created. This problem occurs when all of the following three conditions are met:

  • The static member function is inline.
  • The two calls are from separate files (object modules).
  • The code is optimized.

CAUSE

For a local static object of an inline static member function, the optimizer does not take into account that the static member function may be called from other files.

RESOLUTION

To work around the problem, use one of the following suggestions:

  • Make sure the static member function is not inlined.

          -or-
    
  • Move all calls to the static member function into one file.

          -or-
    
  • Turn off optimizations ( /Od ).

STATUS

Microsoft has confirmed this to be a bug in the products listed at the beginning of this article. We are researching this problem and will post new information here in theMicrosoft Knowledge Base as it becomes available.

However this is not a problem in Microsoft Visual C++ 32-bit edition.

MORE INFORMATION

The following sample code demonstrates this error.

Sample Code

/* Compile options needed : Default release options used by the
   Visual Workbench,or any /O optimizations except /Od.
*/

// test.h

#include <iostream.h>

void TestFunctionA();
void TestFunctionB();

class Object { public:
 int    data;
 Object();
 ~Object();
};

class Static {

 public:
 static int staticFunc();
};

inline int Static::staticFunc() {

 static Object a;
 return a.data++;
}

// test1.cpp

#include "test.h"

void main()
{
 TestFunctionA();
 TestFunctionB();
 TestFunctionA();
 TestFunctionB();
}

void TestFunctionA()
{
 cout << "a.data = " << Static::staticFunc() << endl << flush;
}

// test2.cpp

#include "test.h"

Object::Object() {
 data=1;
 cout << "Constructor call" << endl <<  flush;
}

Object::~Object() {

 cout << "Destructor call" << endl <<  flush;
}

void TestFunctionB()
{
 cout << "a.data = " << Static::staticFunc() << endl << flush;
}

/*  Correct output (no optimizations)  */

Constructor call objectA.data = 1 objectA.data = 2 objectA.data = 3 objectA.data = 4 Destructor call

/*  Wrong output (with optimizations)  */

Constructor call objectA.data = 1 Constructor call objectA.data = 1 objectA.data = 2 objectA.data = 2 Destructor call Destructor call


Additional reference words: 1.00 1.50 buglist1.00 buglist1.50
KBCategory: kbprg kbbuglist
KBSubCategory: CPPLngIss
Keywords : kb16bitonly


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: July 22, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.