GNU扩展在main()启动之前运行C例程的用例

f1tvaqid  于 2023-04-29  发布在  其他
关注(0)|答案(3)|浏览(89)

我一直在阅读一本详细介绍C/C++构建过程的书,其中提到有一个GNU扩展允许您在main()启动之前指定要运行的函数。
对于这样一个函数,有哪些好的用例?这与main()启动后第一件事做有什么区别?我更追求理论上的答案,而不是任何具体的代码。

l7mqbcuq

l7mqbcuq1#

库初始化其全局状态非常有用。没有它,应用程序必须从main()调用库的初始化函数。
标准C运行时中的示例是stdinstdoutstderr的初始化。虽然这些都是由C运行时本身初始化的,但是您引用的特性允许用户编写的库进行类似的初始化。
C++可能使用它来调用全局变量的构造函数。

iqxoj9l9

iqxoj9l92#

您所描述的扩展不适用于正常使用。
正如你所说的那样,在程序开始时调用例程和在程序开始时调用例程没有区别(除非你想在一些标准初始化完成之前)这意味着在某些库的情况下,需要其他库之前没有初始化,你需要在C运行时初始化时运行main()的初始化代码。您描述的特性不是GNU特定的,而是包含在ELF二进制格式中。ELF提供了一个包含两个入口点initfini的加载模块,在加载时首先调用,在卸载前最后调用。此外,还有另一个入口点(通常称为_start,但这可以由链接器更改)作为程序的入口点,通常保留给c运行时模块,结束调用main()
一些库提供了一个init函数,在库加载时调用,以避免强迫用户自己调用一些初始化例程,并确保无论如何都能得到一个正确初始化的库。请记住,这个特性不是在程序加载时完成的,而是在库加载时完成的,但是ELF将程序视为只有一个入口点的库。链接器/加载器通常会选择不同的init例程来调用,其顺序允许库依赖关系被正确初始化(依赖于B的库A使B的init例程在A的init之前被调用)

3htmauhk

3htmauhk3#

我用它来初始化静态存储变量,这些变量放在启动代码没有初始化的段中。
当你从主代码返回时,也会调用一些代码(用于你的清理操作)

相关问题