C++:何时(以及如何)调用 C++ 全局静态构造函数?

时间:2023-04-12
本文介绍了C++:何时(以及如何)调用 C++ 全局静态构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我正在编写一些 C++ 代码,但遇到了一个困扰我一段时间的问题......假设我正在 Linux 主机上使用 GCC 编译 ELF 目标,全局静态目标在哪里调用构造函数和析构函数?

我听说在 crtbegin.o 中有一个函数 _init,在 crtend.o 中有一个函数 _fini.这些是由 crt0.o 调用的吗?或者动态链接器是否真的检测到它们在加载的二进制文件中的存在并调用它们?如果是这样,什么时候它实际上会调用它们?

我主要想知道,这样我就可以了解在我的代码在运行时加载、执行和卸载时幕后发生的事情.

提前致谢!

更新:我基本上是想弄清楚调用构造函数的一般时间.我不想根据这些信息在我的代码中做出假设,或多或少是为了更好地了解我的程序加载时在较低级别发生的事情.我知道这是特定于操作系统的,但我试图在这个问题中缩小范围.

解决方案

当谈到非本地静态对象时,没有太多保证.正如您已经知道的(这里也提到过),它不应该编写依赖于此的代码.静态初始化命令失败...

静态对象经过两个阶段的初始化:静态初始化和动态初始化.前者首先发生,并通过常量表达式执行零初始化或初始化.后者在所有静态初始化完成后发生.例如,这是在调用构造函数时.

一般来说,这个初始化发生在 main() 之前的某个时间.然而,与许多人认为的相反,C++ 标准并不能保证这一点.实际上可以保证的是,初始化是在使用与被初始化的对象相同的翻译单元中定义的任何函数或对象之前完成的.请注意,这不是特定于操作系统的.这是 C++ 规则.这是标准中的引述:

<块引用>它是实现定义的对象的动态初始化(8.5、9.4、12.1、12.6.1)命名空间范围在 main 的第一条语句之前完成.如果初始化推迟到某个时间点在 main 的第一条语句之后的时间,它应该在第一次使用定义的任何函数或对象之前发生在与要初始化的对象相同的翻译单元中

I'm working on some C++ code and I've run into a question which has been nagging me for a while... Assuming I'm compiling with GCC on a Linux host for an ELF target, where are global static constructors and destructors called?

I've heard there's a function _init in crtbegin.o, and a function _fini in crtend.o. Are these called by crt0.o? Or does the dynamic linker actually detect their presence in the loaded binary and call them? If so, when does it actually call them?

I'm mainly interested to know so I can understand what's happening behind the scenes as my code is loaded, executed, and then unloaded at runtime.

Thanks in advance!

Update: I'm basically trying to figure out the general time at which the constructors are called. I don't want to make assumptions in my code based on this information, it's more or less to get a better understanding of what's happening at the lower levels when my program loads. I understand this is quite OS-specific, but I have tried to narrow it down a little in this question.

解决方案

When talking about non-local static objects there are not many guarantees. As you already know (and it's also been mentioned here), it should not write code that depends on that. The static initialization order fiasco...

Static objects goes through a two-phase initialization: static initialization and dynamic initialization. The former happens first and performs zero-initialization or initialization by constant expressions. The latter happens after all static initialization is done. This is when constructors are called, for example.

In general, this initialization happens at some time before main(). However, as opposed to what many people think even that is not guaranteed by the C++ standard. What is in fact guaranteed is that the initialization is done before the use of any function or object defined in the same translation unit as the object being initialized. Notice that this is not OS specific. This is C++ rules. Here's a quote from the Standard:

It is implementation-defined whether or not the dynamic initialization (8.5, 9.4, 12.1, 12.6.1) of an object of namespace scope is done before the first statement of main. If the initialization is deferred to some point in time after the first statement of main, it shall occur before the first use of any function or object defined in the same translation unit as the object to be initialized

这篇关于C++:何时(以及如何)调用 C++ 全局静态构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:使用 -static-libgcc -static-libstdc++ 编译仍然会导致对 libc.so 的动态依赖 下一篇:GCC 中的 std::put_time 实现状态?

相关文章