BUG: extern Declaration Generates Extra Constructor Call

ID: Q167359


The information in this article applies to:


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.


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.

Additional query words:


Keywords          : kbcode kbtool kbVC400bug kbVC410bug kbVC420bug kbVC500bug kbVC600bug 
Version           : winnt:4.0,4.1,4.2,5.0,6.0
Platform          : winnt 
Issue type        : kbbug 

Last Reviewed: May 17, 1999