BUG: L2025 With Static Object in Inline Function

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

The information in this article applies to:

 The Microsoft C Run-time (CRT), included with
  -  Microsoft Visual C++ for Windows, versions 1.0 and 1.5

SYMPTOMS

When an inline function with a local static object is called from two different object modules, two different objects are created, generating the following error message:

     L2025: symbol: symbol defined more than once

where symbol is the mangled function name.

This problem only occurs when the following two conditions are met:

  • The function with the static object is inline.
  • The two calls are from separate files (object modules).

CAUSE

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

RESOLUTION

To work around this problem, use one of the following methods:

  • Make sure that the function with the static object is not inlined.

    -or-

  • Move all calls of the static member function into one file.

STATUS

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

This is not a problem in Visual C++ 32-bit Edition.

MORE INFORMATION

The following sample code demonstrates this problem:

Sample Code

/* Compile options needed : none
*/

// test.h

   #include <iostream.h>

   void TestFunctionA();
   void TestFunctionB();

   class Object
   {
      public:
      int data;   // Will track the number of accesses to an
                  // object of class Object.
      Object();   // Provides screen output each time
                  // constructor is called.
      ~Object();  // Provides screen output each time
                  // destructor is called.
   };

   inline int staticFunc()
   {
       static Object objectA;    // This object should be
                                 // created only once.
       return objectA.data++;    // Increment objectA's
                                 // access counter.
   }

// test1.cpp

   #include "test.h"

   void main()
   {
      TestFunctionA();    // Should construct objectA.
      TestFunctionB();    // Should increment objectA.data.
   }

   void TestFunctionA()
   {
      cout << "objectA.data = " << staticFunc() << endl;
   }

// test2.cpp

   #include "test.h"

   Object::Object()
   {
      data=1;             // Initialize access count to 1.
      cout << "Constructor call" << endl;
   }

   Object::~Object()
   {
      cout << "Destructor call" << endl;
   }

   void TestFunctionB()
   {
      cout << "objectA.data = " << staticFunc() << endl;
   }


Additional reference words: 1.00 1.50 inline static object
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.