在main()之前可能需要做什么样的操作

dab*_*aid 19 c c++ program-entry-point

我遇到了这个问题,询问如何在C中的main()之前执行代码,并提到C++的策略.我主要住在应用程序空间,所以在main()之前执行从未发生过.什么样的东西需要这种技术?

Edw*_*nge 14

"什么样的东西需要这种技术?"

事实:没有.

但是,由于各种原因,您可能需要在main之前做很多有用的事情.仅举一个实际例子,假设您有一个构建doohickies的抽象工厂.您可以确保构建工厂实例,将其分配到某个特殊区域,然后将各种具体的doohickies注册到它...是的,您可以这样做.

另一方面,如果您将工厂实现为单例并使用全局值初始化的事实来"欺骗"实现在主要启动之前注册具体的doohickies,您可以以很少的成本获得多个好处(使用单例的事实,基本上这里没有问题,几乎是唯一的问题.

例如你:

  1. 不必维护必须明确调用的所有注册列表.实际上,您甚至可以在私有范围内声明和定义整个类,在任何人看不到的情况下,并且在程序启动时可以使用它.

  2. main()不需要用一堆它不关心的对象做一堆垃圾.

所以,这些都不是必需的.但是,如果您利用在主要开始之前初始化全局变量的事实,则可以减少耦合和维护问题.

编辑:

请注意,我已经了解到语言无法保证这一点.C++只保证在main之前发生常量初始化.我在这个答案中谈到的是动态初始化.这个C++保证在第一次使用变量之前发生,就像函数本地静态变量一样.

虽然每个编译器似乎都在main之前进行动态初始化.我以为我碰到了一次没有,但我相信问题的根源是别的.


jsc*_*ier 5

该技术可用于库初始化例程或初始化将在程序执行期间隐式使用的数据.


GCC提供构造函数析构 函数属性,这些属性分别导致在执行进入main()main()已完成或exit()已被调用之前自动调用函数.

void __attribute__ ((constructor)) my_init(void);
void __attribute__ ((destructor)) my_fini(void);
Run Code Online (Sandbox Code Playgroud)

在库初始化的情况下,dlopen()如果在运行时加载库,则在返回之前执行构造函数例程,如果在加载时加载库,则在main()启动之前执行构造函数例程.当用于库清理时,dlclose()如果在运行时加载库,则在执行之前执行析构函数例程,如果在加载时加载库,则在exit()完成之后执行析构函数例程main().