BUG: extern Declaration Generates Extra Constructor Call

Last reviewed: July 14, 1997
Article ID: Q167359
The information in this article applies to:
  • Microsoft Visual C++, 32-bit Editions, versions 4.0, 4.1, 4.2, 5.0

SYMPTOMS

An extern declaration incorrectly causes an extra constructor call when the extern declaration and the global declaration appear in the same translation unit.

NOTE: Here, translation unit means the source file and any included files considered as though they were all one file. Please see the example code below.

RESOLUTION

There are many potential workarounds. The basic condition is that the extern declaration cannot appear after the global variable declaration in the same translation unit. One of the easiest ways to assure this condition is to place the offending global variable declaration(s) in a source file of their own that is included in the project, but not included in any other source files (please see the example code below).

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

Sample Code

    /* Compile Options Needed: /GX */
    // File MyClass.h

    #include <iostream>

    #pragma once

    struct MyClass {
       MyClass()
                {std::cout << "MyClass ctor Exectuing" << std::endl;}
    };

    MyClass X;
    // End File MyClass.h

    // File main.cpp
    #include "myclass.h"

    extern MyClass X;

    int main()
    {
       return 0;
    }
    // End File main.cpp

When you build and run the code above, you will see that MyClass::MyClass() is being called twice. One of the calls is generated by the global variable declaration in the file MyClass.h and the other by the extern declaration in the file main.cpp. One possible workaround is to remove the declaration of the global variable X from MyClass.h above and create a third file, "globals.cpp" that contains the declaration of the global variable X. By doing this, the declaration of the global variable resides in a different translation unit than the extern declaration(s).

    /* Compile Options Needed: /GX */
    // File MyClass.h

    #include <iostream>

    #pragma once

    struct MyClass {
       MyClass()
                {std::cout << "MyClass ctor Exectuing" << std::endl;}
    };

    // End File MyClass.h

    // File Globals.cpp
    #include "MyClass.h"

    MyClass X;
    // End File Globals.cpp

    // File main.cpp
    #include "myclass.h"

    extern MyClass X;

    int main()
    {
       return 0;
    }
    // End File main.cpp

When you build and run the program, it will now show that MyClass::MyClass() is only called once.


Keywords : CLngIss CodeGen kbcode kbtool vcbuglist500
Version : 4.0 4.1 4.2 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: July 14, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.