POD全局对象初始化 [英] POD global object initialization

查看:420
本文介绍了POD全局对象初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我今天被一个错误咬了。



C ++律师的问题



以下源代码:

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

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

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

请注意,所有值在编译时都已知,MyPod是POD 。



包含自包含源的详细信息



以下源代码可再现错误,可以复制/粘贴到主文件中。 cpp文件:

  #include< iostream> 

// SomeGlobalObject的点是为它的
//构造函数在main之前启动
// ...
struct SomeGlobalObject
{
SomeGlobalObject();
};

// ...
//这解释了全局对象
SomeGlobalObject oSomeGlobalObject;

// A POD ...我希望它将被构造在
//使用参数列表时编译时
struct MyPod
{
short m_short;
const char * const m_string;
};

//声明/ MyPod数组的初始化
MyPod myArrayOfPod [] =
{{1,Hello},{2,World},{3, ! }};

//声明/初始化void数组的数组
void * myArrayOfVoid [] [2] =
{{(void *)1,Hello} ,{(void *)2,World},{(void *)3,! }};

//全局对象的构造函数...启动BEFORE main
SomeGlobalObject :: SomeGlobalObject()
{
//这两个值应为1
std :: cout<< myArrayOfPod [0] .m_short:< myArrayOfPod [0] .m_short<< std :: endl;
std :: cout<< myArrayOfVoid [0] [0]:< myArrayOfVoid [0] [0]< std :: endl;
}

// main ...还有什么?
int main(int argc,char * argv [])
{
return 0;
}

MyPod是POD,我相信不会有构造函数。



因此,全局对象 SomeGlobalObject 将没有问题使用全局数组



但是,在Visual C ++ 2008中,在调试模式下,执行 myArrayOfPod 即使 myArrayOfVoid 被正确初始化,它也被初始化(所有的值都是零编号)。



C ++编译器不应在编译时初始化全局POD(包括POD结构)?



Displaimer



注意,我知道全局变量是邪恶的,我知道不能确定在不同编译单元中声明的全局变量的创建顺序,但是这是不合适的:问题是关于全局POD初始化。



编辑



我在Ubuntu上复制/粘贴此代码就像g ++ 4.4.3一样,这两个数组在调试和发布模式下都被正确初始化。



这个行为被报告给Microsoft,并等待确认:
https:// connect .microsoft.com / VisualStudio / feedback / details / 564844 / pod-struct-global-object-initialization-uses-constructor



编辑2



Visual C ++ QA回答了错误提交,引用标准(至少 n3092 )。就他们而言,在Visual C ++上看到的行为遵循标准。



尽管我的感觉这仍然是一个错误,我必须承认事实他们知道标准无限多于我所做的(如果只是因为使用语言,当他们为语言编写编译器时),因此接受他们的答案。 p>

所以,我会做我的家庭作业,也就是说,我会阅读 n3092 从头到尾(一千页律师般的陈述...这是我的运气...):本文档使用了很多明确定义的词,如果我不知道每个词的确切含义,那么我没有办法引用一些 n3092 段落支持我的观点...



MSN AndreyT


解决方案

根据C ++标准,3.6.2.2:初始化非本地对象:


同时,零初始化和
常量初始化称为
静态初始化;所有其他
初始化是动态
初始化。静态初始化
应在任何动态
初始化之前执行。


myArrayOfPod 至少乍一看用一个常量表达式初始化,它应该在 oSomeGlobalObject 之前初始化。事实上,它不在调试可能是一个错误。您可以通过 connect.microsoft.com 提交错误。


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.

解决方案

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.

这篇关于POD全局对象初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆