我今天被虫子咬了。
问 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。
那么,myArrayOfPod 应该在编译时初始化,还是编译器会生成 MyPod 的默认构造函数?
详细信息,包括独立的源
可以将重现错误的以下源复制/粘贴到 main.cpp 文件中:
#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 作为一个 POD,我相信不会有构造函数。仅在编译时初始化。
因此,全局对象SomeGlobalObject
在构建时使用 POD 的全局数组是没有问题的。
但是,在 Visual C++ 2008 中,在调试模式下,执行时myArrayOfPod
未正确初始化(其所有值均为零),即使myArrayOfVoid
已正确初始化。
所以我的问题是:C++ 编译器不应该在编译时初始化全局 POD(包括 POD 结构)吗?
责备者
请注意,我知道全局变量是邪恶的,并且我知道无法确定在不同编译单元中声明的全局变量的创建顺序,但这超出了主题:问题是关于全局 POD 初始化。
Edit
我在 Ubuntu 上复制/粘贴了这段代码,就 g++ 4.4.3 而言,这两个数组在调试和发布模式下都正确初始化。
该行为已报告给 Microsoft,正在等待确认: https://connect.microsoft.com/VisualStudio/feedback/details/564844/pod-struct-global-object-initialization-uses-constructorhttps://connect.microsoft.com/VisualStudio/feedback/details/564844/pod-struct-global-object-initialization-uses-constructor https://connect.microsoft.com/VisualStudio/feedback/details/564844/pod-struct-global-object-initialization-uses-constructor
Edit 2
Visual C++ QA 回答了 bug 提交,引用了标准(至少,n3092 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3092.pdf)。就他们而言,在 Visual C++ 上看到的行为确实遵循标准。
尽管我“感觉”这仍然是一个错误,但我必须承认他们比我更了解标准(如果只是因为我使用该语言,当他们编写编译器时)对于语言),从而接受他们的答案。
所以,我会做作业,也就是说,我会读书n3092 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3092.pdf从头到尾(一千页律师般的陈述...这是我的运气...):这份文件使用了很多定义明确的单词,如果我不知道每个单词的确切含义,那么我就无法引用一些n3092 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3092.pdf段落来支持我的观点...
谢谢MSN https://stackoverflow.com/users/6210/msn and AndreyT https://stackoverflow.com/users/187690/andreyt寻求他们的答案。