Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

POD global object initialization

I've got bitten today by a bug.

Question for the C++ lawyers

Let's consider the following source :

struct MyPod
{
   short              m_short ;
   const char * const m_string ;
} ;

MyPod myArrayOfPod[] = { { 1, "Hello" } } ;

int main(int argc, char * argv[])
{
   return 0 ;
}

Note that all values are known at compile time, and that MyPod is a POD.

So, should myArrayOfPod be initialized at compile time, or will some default constructor of MyPod be generated by the compiler ?

Details including a self-contained source

The following source which reproduces the error, can be copy/pasted into a main.cpp file:

#include <iostream>

// The point of SomeGlobalObject is for its
// constructor to be launched before the main
// ...
struct SomeGlobalObject
{
   SomeGlobalObject() ;
} ;

// ...
// Which explains the global object
SomeGlobalObject oSomeGlobalObject ;

// A POD... I was hoping it would be constructed at
// compile time when using an argument list
struct MyPod
{
   short              m_short ;
   const char * const m_string ;
} ;

// declaration/Initialization of a MyPod array
MyPod myArrayOfPod[] = 
{ { 1, "Hello" }, { 2, "World" }, { 3, " !" } } ;

// declaration/Initialization of an array of array of void *
void * myArrayOfVoid[][2] = 
{ { (void *)1, "Hello" }, { (void *)2, "World" }, { (void *)3, " !" } } ;

// constructor of the global object... Launched BEFORE main
SomeGlobalObject::SomeGlobalObject()
{
   // The two values should be "1"
   std::cout << "myArrayOfPod[0].m_short : " << myArrayOfPod[0].m_short << std::endl ;
   std::cout << "myArrayOfVoid[0][0] : " << myArrayOfVoid[0][0] << std::endl ;
}

// main... What else ?
int main(int argc, char* argv[])
{
   return 0 ;
}

MyPod being a POD, I believed there would be no constructors. Only initialization at compile time.

Thus, the global object SomeGlobalObject would have no problem to use the global array of PODs upon its construction.

But, in Visual C++ 2008, on debug mode, upon execution myArrayOfPod is not properly initialized (all its values are zero-ed), even if myArrayOfVoid is correctly initialized.

So my questions is: Are C++ compilers not supposed to initialize global PODs (including POD structures) at compilation time ?

Displaimer

Note that I know global variable are evil, and I know that one can't be sure of the order of creation of global variables declared in different compilation units, but this is out-of-topic: The question is about global POD initialization.

Edit

I copy/pasted this code on my Ubuntu, and as far as g++ 4.4.3 is concerned, the two arrays are correctly initialized in both debug and release mode.

The behaviour was reported to Microsoft, and awaiting confirmation: https://connect.microsoft.com/VisualStudio/feedback/details/564844/pod-struct-global-object-initialization-uses-constructor

Edit 2

Visual C++ QA answered the bug submission, quoting the standard (at least, n3092). As far as they are concerned, the behaviour seen on Visual C++ does follow the standard.

And despite my "feeling" this is still a bug, I must acknowledge the fact they know the standard infinitely more than I do (if only because I use the language, when they write a compiler for the language), and thus accept their answer.

So, I'll do my homework, that is, I'll read n3092 from start to end (A thousand pages of lawyer-like statements... This is my luck...): This document uses a lot of well-defined words, and if I don't know the exact meaning of each word, then there's no way I can quote some n3092 paragraph to support my viewpoint...

Thanks to MSN and AndreyT for their answers.

like image 358
paercebal Avatar asked Feb 25 '26 15:02

paercebal


1 Answers

According to the C++ standard, 3.6.2.2: Initialization of non-local objects:

Together, zero-initialization and constant initialization are called static initialization; all other initialization is dynamic initialization. Static initialization shall be performed before any dynamic initialization takes place.

Since myArrayOfPod is at least at first glance initialized with a constant expression, it should be initialized before oSomeGlobalObject. The fact that it isn't in debug is probably a bug. You can submit a bug through connect.microsoft.com.

like image 101
MSN Avatar answered Feb 28 '26 05:02

MSN