我正在开发一个项目,其中包含调用 main
之前的启动代码。然而我不知道 std 库初始化。
我知道下面的代码会抛出段错误。
#include <iostream>
void foo(void) __attribute__((constructor));
void foo() {
std::cout << "foo" << std::endl;
}
int main() {
std::cout << "Simple program to throw a segmentation fault" << std::endl;
}
上面的代码可以通过使用std::ios_base::Init mInitializer;
强制初始化ostream缓冲区(不确定它是否完全是ostream)来工作。这意味着 std 库此时尚未完全初始化(这是我对上面示例的推断)。
那么什么时候我可以使用 std 函数而不实际破坏代码呢?有没有办法强制初始化完整的std库?
最佳答案
documentation for the constructor
attribute说的是:
However, at present, the order in which constructors for C++ objects with static storage duration and functions decorated with attribute
constructor
are invoked is unspecified.
这意味着 ELF 构造函数和静态对象(如用于初始化 std::cout
的对象)不能很好地混合。
另一方面,std::cout
是一个历史异常,因为它不依赖于 C++ 标准库中的构造函数。在 ELF 系统上,ELF 构造函数按拓扑顺序运行。这意味着动态链接器会查看库依赖项(DT_NEEDED
条目)并在其依赖项初始化之前延迟库的初始化。
因此,当 ELF 构造函数运行并构造应用程序定义的全局对象时,C++ 代码可以假定 C++ 运行时库已完全初始化。唯一的异常(exception)是 C++ 库,它会抢占标准 C++ 标准库本身使用的例程(通过 ELF 符号插入),并且如果库之间存在循环依赖关系,则不会出现正确的初始化顺序。这两种情况并不常见,除非您编写自定义 malloc
或类似的内容,否则可以通过正确的应用程序设计来避免。
关于c++ - 在运行时,std 库何时完全初始化以便在不破坏代码的情况下使用它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50697952/