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...