【问题标题】:Compiler specific memory initialization编译器特定的内存初始化
【发布时间】:2012-04-29 05:34:10
【问题描述】:

有没有办法保证整个程序中某些对象的静态对象初始化顺序。我有内存分配器,我希望将它们作为程序中的第一件事分配,因为它们将在整个程序的其他地方使用,我想使用这些分配器来分配所有以后的内存。

我知道这可能是特定于编译器的,因为我不相信 C++ 标准允许这样做。我感兴趣的两个编译器是 gcc 和 VS2010 的编译器。如果有办法,有人可以解释一下吗?

编辑

我不想“在第一次使用时构造”,因为分配器将分配我想在程序开始时初始化的大块内存。

【问题讨论】:

  • 你的意思是“保证静态对象初始化的顺序”还是什么?
  • 您可能想重写您的问题。因为它的方式没有多大意义
  • @Grizzly:这有什么不妥之处?
  • 主要是这样的:“有没有办法确保在程序中首先分配某些内存?”。你这到底是什么意思。你的意思是静态对象的初始化顺序吗?你的意思是什么内存,应该在什么时候初始化?
  • @Grizzly:我确实说过“我想确保某些对象的静态对象初始化的顺序”和“何时应该初始化它”我说“首先分配”。

标签: c++ visual-studio visual-studio-2010 memory gcc


【解决方案1】:

您可以通过使用特定于编译器的指令来影响初始化的顺序。 MSVC 有一个编译指示

#pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )

这可以在某种程度上设置特定模块的优先级。有关init_seg,请参阅此参考。

gcc 编译器具有类似/相关的属性语法,用于设置特定初始化的 relative 优先级。看起来是这样的

Some_Class  A  __attribute__ ((init_priority (2000)));
Some_Class  B  __attribute__ ((init_priority (543)));

并在init_priority的此页面上进行了解释。

【讨论】:

  • 非常有趣。你能提供一个如何为 MSVC 做 Some_Class 的例子吗?
  • @Bo Persson:您能否展示一个用于 MSVC 的 Some_Class 示例?阅读文档后,我看不出与 Some_Class A 类似的东西是如何可能的(尽管我确实相信这是可能的,但文档中说的是,但我似乎无法实现它)。
  • 您无法为 MSVC 获得完全相同的功能。您可以将#pragma init_seg(lib) 添加到初始化Some_Class 对象的文件中,以在用户代码之前对其进行初始化。您无法为每个单独的对象获得确切的优先级。
【解决方案2】:

我猜你指的是静态初始化顺序惨败,当基于另一个静态变量的状态初始化静态变量时,你的程序有机会调用未定义的行为(可能有也可能没有当时调用了它的构造函数)。

解决此问题的方法是 construct on first use 习语,在此处的 C++ FAQ 中有描述:

http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.15

【讨论】:

  • 我之前研究过这个,但是,我不希望“首次使用时构造”,因为分配器将分配我想在程序开始时初始化的大块内存。跨度>
  • @chadb:也许你应该更详细地描述你在做什么。因为根据您的问题,我会假设第一次使用时构造非常好(请注意,第一次使用可以在静态对象的构造中)。
  • 因此,您将让第一个初始化程序触发您的内存分配以尝试使用它。
  • @ams:这需要检查每个内存分配。这绝对不理想。
  • 不,不理想,但无论如何你都要检查返回结果,对吧?简单的 NULL 指针检查要贵多少。您可以拥有一个仅在静态初始化程序中使用的特殊函数,以及在普通代码中使用的另一个函数,这样一旦保证初始化就不会产生开销(即使那样,我也建议使用断言,它当你进行发布模式构建时,你会编译出来)。
【解决方案3】:

与其尝试控制静态初始化(这只会导致您在未来花费数小时或更长时间的荒谬调试时间),不如在main 的开头分配您的内存池。然后,您仍然可以获得预先分配的内存,而不会遇到静态初始化的所有缺陷。

【讨论】:

  • 对于所有在 main 之前运行并依赖于相关内存的静态初始化程序来说,这有点晚了。
  • 哈佛拱门。处理器可能需要静态初始化才能将数据存储在程序存储器上,通常是 AVR uC 上的只读闪存。作为只读内存,您不能运行时分配或初始化。
猜你喜欢
  • 2021-09-08
  • 2019-11-04
  • 2015-01-11
  • 2010-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-09
相关资源
最近更新 更多