程序执行总是从C中的main开始吗?

时间:2011-08-01 11:29:55

标签: c c-preprocessor pragma preprocessor-directive

必须从main开始执行程序,还是可以修改起始地址?

#include <stdio.h>

void fun();

#pragma startup fun

int main()
{
    printf("in main");
    return 0;
}

void fun()
{
    printf("in fun");
}

此程序会在in fun之前打印in main

3 个答案:

答案 0 :(得分:9)

  

在ANSI标准中指定'#pragma'命令以具有任意实现定义的效果。在GNU C预处理器中,'#pragma'首先尝试运行游戏'流氓';如果失败,它会尝试运行游戏'hack';如果失败了,它会尝试运行显示河内塔的GNU Emacs;如果失败,则会报告致命错误。无论如何,预处理不会继续。

- Richard M. Stallman,GNU C预处理器,版本1.34

程序执行从启动代码或“运行时”开始。这通常是一些名为_start的汇编程序例程,或者某些程序员(在Unix机器上)位于编译器程序包附带的文件crt0.o中。它执行运行C可执行文件所需的设置(例如,设置stdinstdoutstderratexit()使用的向量...对于C ++,它还包括初始化全局对象,即运行它们的构造函数)。只有这样才能控制跳转到main()

由于我的答案开头的引用如此雄辩地表达,#pragma所做的完全取决于你的编译器。检查其文档。 (我猜你的pragma startup - 顺便说一句,前面加上# - 告诉运行时首先调用fun() ...)

答案 1 :(得分:1)

就ISO C标准而言,C程序的入口点始终为main(除非使用某些实现定义的功能覆盖它)用于托管实现。对于“独立实现”(通常是嵌入式系统,通常没有操作系统),入口点是实现定义的。

答案 2 :(得分:0)

C程序不一定从main()函数开始。某些代码在main()之前执行,它将所有未初始化的全局变量清零并使用适当的值初始化其他全局变量。例如,请考虑以下代码:

int a;
int b = 10;

int main()
{
    int c = a * b;
    return 0;
}

在上面的示例代码中,ab分别在执行0中的第一行之前分配了10main()

#pragma指令用于定义实现定义的行为。使用#pragma的代码可能会在某些编译器中编译,但可能无法在另一个编译器中编译。