在main()之前执行代码
在面向对象语言(C ++)中,您可以使用全局对象或类静态对象在main()
之前执行代码,并让它们的构造函数运行您想要的代码。
有没有办法在C中这样做? 我没有任何具体问题我想解决,我只是好奇。 这可能有用的一件事是自动初始化库。
有一些使用__attribute__
方法,但这些方法非常特定于您的编译器,使用这些编写的代码实际上不是可移植的。 另一方面,C语言不提供任何启动模块/库。
在C中,逻辑上main()
是OS调用的第一个函数。 但在调用main()
之前,操作系统调用另一个称为start-up
模块的函数来设置各种环境变量,初始化(未初始化)静态变量,构建堆栈帧(激活记录)并初始化堆栈指针到启动堆栈区域和其他必须在调用main()
之前完成的任务。
假设您正在编写嵌入式系统的代码,其中没有或只有最小的操作系统来执行上述工作,那么您应该探索这些依赖于编译器的选项。 除了GCC之外,Turbo-C和Microsoft C编译器还提供了在特定硬件机器中添加代码的function(fe 8086机器)。
IOW,启动模块不适合程序员。
你可以用__attribute__ ((constructor))
来做。 我用gcc
和clang
测试了以下示例。 话虽如此,它不是语言的一部分。
#include void __attribute__ ((constructor)) premain() { printf("premain()\n"); } int main(int argc, char *argv[]) { printf("main()\n"); return 0; }
它执行以下操作:
$ ./test premain() main()
使用gcc,您可以使用构造函数属性,例如
__attribute__ ((__constructor__)) void foo(void) { ... }
这将在main之前调用foo。
注意:这可能无法移植到其他编译器。
您可以初始化全局变量,但不能在这些初始化中调用函数。
不是以任何符合标准的方式,但是你应该深入了解操作系统加载二进制映像并调用应用程序主函数时真正发生的事情!
有一些可移植的方法来指定可以在执行main之后执行的function。
-
atexit()
-
at_quick_exit()
此外,请按照此链接以及C ++中的各种类型的初始化 – 这可能对您在调用main()之前执行代码很有用。