在main()之前执行代码

时间:2012-01-03 14:08:11

标签: c

在面向对象语言(C ++)中,您可以使用全局对象或类静态对象在main()之前执行代码,并让它们的构造函数运行您想要的代码。

有没有办法在C中这样做?我没有任何具体问题我想解决,我只是好奇。这可能有用的一件事是自动初始化库。

6 个答案:

答案 0 :(得分:16)

您可以使用__attribute__ ((constructor))执行此操作。我已使用gccclang测试了以下示例。话虽这么说,但不是语言的一部分。

#include <stdio.h>

void __attribute__ ((constructor)) premain()
{
    printf("premain()\n");
}

int main(int argc, char *argv[])
{
    printf("main()\n");
    return 0;
}

它执行以下操作:

$ ./test
premain()
main()

GCC将其记录在:https://gcc.gnu.org/onlinedocs/gcc-8.3.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes

答案 1 :(得分:9)

有使用__attribute__的方法,但这些方法非常特定于您的编译器,使用这些编写的代码非常便携。另一方面,C语言不提供任何启动模块/库。

在C中,逻辑上main()是OS调用的第一个函数。但在调用main()之前,操作系统调用另一个名为start-up模块的函数来设置各种环境变量,初始化(未初始化)静态变量,构建堆栈帧(激活记录)并初始化堆栈指针在调用main()之前必须完成堆栈区域的开始和其他任务。

如果您正在编写嵌入式系统的代码,其中没有或只有最小的操作系统来执行上述工作,那么您应该探索这些依赖于编译器的选项。除了GCC之外,Turbo-C和Microsoft C编译器还提供了在特定硬件机器中添加代码的功能(例如,8086机器)。

换句话说,启动模块不适合程序员。

答案 2 :(得分:4)

使用gcc,您可以使用构造函数属性,例如

__attribute__ ((__constructor__)) 
void foo(void) {
        ...
}

这将在main之前调用foo。

注意:这可能无法移植到其他编译器。

答案 3 :(得分:0)

您可以初始化全局变量,但不能在这些初始化中调用函数。

答案 4 :(得分:0)

不符合任何符合标准的方式,但您应该深入了解操作系统加载二进制映像并调用应用程序主函数时真正发生的事情!

答案 5 :(得分:0)

可以通过便携式方式指定可执行的功能&#34;&#34;主要执行。

  1. atexit()

  2. at_quick_exit()

  3. 此外,请关注this链接以及C ++中各种类型的初始化 - 这对于在调用main()之前执行代码可能很有用。