POD全局对象初始化

2023-12-25

我今天被虫子咬了。

问 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寻求他们的答案。


根据C++标准,3.6.2.2:非局部对象的初始化:

一起,零初始化和 调用常量初始化 静态初始化;所有其他 初始化是动态的 初始化。静态初始化 应在任何动态之前执行 发生初始化。

Since myArrayOfPod至少乍一看是用常量表达式初始化的,它应该在之前初始化oSomeGlobalObject。事实上它没有处于调试状态可能是一个错误。您可以通过以下方式提交错误连接.microsoft.com http://connect.microsoft.com.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

POD全局对象初始化 的相关文章

  • 在C语言中使用“void”

    我很困惑为什么我们需要通过void转换为 C 函数 int f void return 0 versus int f return 0 什么是正确的做法以及为什么 In C int f 是一种老式的声明 它说f需要固定但未指定数量和类型的参
  • 查找哪些页面不再与写入时复制共享

    假设我在 Linux 中有一个进程 我从中fork 另一个相同的过程 后forking 因为原始进程将开始写入内存 Linux写时复制机制将为进程提供与分叉进程使用的不同的唯一物理内存页 在执行的某个时刻 我如何知道原始进程的哪些页面已被写
  • 进程何时获得 SIGABRT(信号 6)?

    C 中进程获得 SIGABRT 的场景有哪些 该信号是否始终来自进程内部 或者该信号可以从一个进程发送到另一个进程吗 有没有办法识别哪个进程正在发送该信号 abort 向调用进程发送SIGABRT信号 就是这样abort 基本上有效 abo
  • C#动态支持吗?

    看完之后这个帖子 https stackoverflow com questions 2674906 when should one use dynamic keyword in c sharp 4 0k和链接 我还有 2 个问题 问题 1
  • 32 位应用程序的特征最大矩阵大小

    所以 我正在寻找Eigen http eigen tuxfamily org index php title Main Page当我尝试声明大于 10000x10000 的矩阵时 包崩溃 我需要声明一个像这样的矩阵 可靠地大约有 13000
  • 从 MVC 迁移到 ASP.NET Core 3.1 中的端点路由时,具有角色的 AuthorizeAttribute 不起作用

    我正在尝试将我的项目从 UseMVC asp net core 2 2 兼容样式 升级到 UseEndpoint Routing 并且我的所有请求都被重定向到我的验证失败页面 它与声明有关 如果我删除 Authorize Roles Adm
  • C++:重写已弃用的虚拟方法时出现弃用警告

    我有一个纯虚拟类 它有一个纯虚拟方法 应该是const 但不幸的是不是 该接口位于库中 并且该类由单独项目中的其他几个类继承 我正在尝试使用这个方法const不会破坏兼容性 至少在一段时间内 但我找不到在非常量方法重载时产生警告的方法 以下
  • Clang 编译器 (x86):80 位长双精度

    我正在尝试在 x86 Windows 平台上使用本机 80 位长双精度 海湾合作委员会选项 mlong double 80 https gcc gnu org onlinedocs gcc x86 Options html似乎不适用于 cl
  • 如何使用recv()检测客户端是否仍然连接(并且没有挂起)?

    我写了一个多客户端服务器程序C on SuSE Linux 企业服务器 12 3 x86 64 我为每个客户端使用一个线程来接收数据 我的问题是 我使用一个终端来运行服务器 并使用其他几个终端来运行服务器telnet到我的服务器 作为客户端
  • 如何配置 WebService 返回 ArrayList 而不是 Array?

    我有一个在 jax ws 上实现的 java Web 服务 此 Web 服务返回用户的通用列表 它运行得很好 Stateless name AdminToolSessionEJB RemoteBinding jndiBinding Admi
  • ASP MVC:服务应该返回 IQueryable 的吗?

    你怎么认为 你的 DAO 应该返回一个 IQueryable 以便在你的控制器中使用它吗 不 您的控制器根本不应该处理任何复杂的逻辑 保持苗条身材 模型 而不是 DAO 应该将控制器返回给视图所需的所有内容 我认为在控制器类中看到查询 甚至
  • IronPython:没有名为 json 的模块

    我安装了 IronPython 我的 python 文件如下所示 import sys print sys version import json 运行它的代码 var p Python CreateEngine var scope p C
  • 如何识别 WPF 文本框中的 ValidationError 工具提示位置

    我添加了一个箭头来指示工具提示中的文本框 当文本框远离屏幕边缘时 这非常有效 但是当它靠近屏幕边缘时 工具提示位置发生变化 箭头显示在左侧 Here is the Image Correct as expected since TextBo
  • 将数据打印到文件

    我已经超载了 lt lt 运算符 使其写入文件并写入控制台 我已经为同一个函数创建了 8 个线程 并且我想输出 hello hi 如果我在无限循环中运行这个线程例程 文件中的o p是 hello hi hello hi hello hi e
  • Azure 事件中心 - 按顺序接收事件

    我使用下面的代码从 Azure Event Hub 接收事件 https learn microsoft com en us azure event hubs event hubs dotnet framework getstarted s
  • 当“int”处于最大值并使用 postfix ++ 进行测试时,代码定义良好吗?

    示例 未定义行为的一个示例是整数溢出的行为 C11dr 3 4 3 3 int溢出是未定义的行为 但这是否适用于存在循环的以下内容 并且不使用现在超出范围的副作用i 特别是 这是否后缀增量规格帮助 结果的值计算在副作用之前排序 更新操作数的
  • 如何挤出平面 2D 网格并赋予其深度

    我有一组共面 连接的三角形 即二维网格 现在我需要将其在 z 轴上挤出几个单位 网格由一组顶点定义 渲染器通过与三角形数组匹配来理解这些顶点 网格示例 顶点 0 0 0 10 0 0 10 10 0 0 10 0 所以这里我们有一个二维正方
  • 在类的所有方法之前运行一个方法

    在 C 3 或 4 中可以做到这一点吗 也许有一些反思 class Magic RunBeforeAll public void BaseMethod runs BaseMethod before being executed public
  • 运算符“==”不能应用于“int”和“string”类型的操作数

    我正在编写一个程序 我想到了一个数字 然后计算机猜测了它 我一边尝试一边测试它 但我不断收到不应该出现的错误 错误是主题标题 我使用 Int Parse 来转换我的字符串 但我不知道为什么会收到错误 我知道它说 不能与整数一起使用 但我在网
  • 带重定向标准流的 C# + telnet 进程立即退出

    我正在尝试用 C 做一个 脚本化 telnet 项目 有点类似于Tcl期望 http expect nist gov 我需要为其启动 telnet 进程并重定向 和处理 其 stdin stdout 流 问题是 生成的 telnet 进程在

随机推荐