c++ - 在运行时,std 库何时完全初始化以便在不破坏代码的情况下使用它?

标签 c++ gcc std libc static-initialization

我正在开发一个项目,其中包含调用 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/

相关文章:

c++ - std::move 实现

c++ - 如何零初始化 union ?

c++ - 为什么header中的全局变量ofstream不能用C++写文件?

c - `clear` 导致 undefined reference 错误

c++ - 未显示 libstdc++-v3 中的 GCC 源代码修改

c++ - 指向 Eigen3 vector 的 std::list 的指针或引用

c++类方法回调类似于std::thread

c++ - MergeSort 打印出奇怪的数字!无法在调试中跟踪

c - 错误 : initializer element is not computable at load time

C++ 长 switch 语句还是用 map 查找?