编译器如何知道我的主要功能在哪里?

时间:2015-06-26 07:06:12

标签: c main

我正在开发一个包含多个模块(源文件,头文件,库)的项目。所有汤中的一个文件包含我的主要功能。

我的问题是:

  • 编译器如何知道要编译哪些模块?哪些模块不知道?
  • 编译器如何识别内部带有main()的模块?

3 个答案:

答案 0 :(得分:2)

编译器本身并不关心哪个文件包含哪些函数; main()并不特别。但是,在链接阶段,来自不同文件(和可能的编译单元)的所有这些符号都是匹配的。链接器有一个隐藏的“模板”,其代码位于固定地址,操作系统在运行程序时将始终调用该地址。该代码会调用您的main;因此,链接器在所有文件中查找main。如果不存在,则会出现未解决的符号错误,就像您使用了一个忘记实现的功能一样。

与任何其他功能相同,适用于main:您只能拥有一个实施;在两个链接在一起的文件中有两个main,会出现链接器错误,因为链接器无法决定使用哪个。

答案 1 :(得分:1)

  

编译器如何知道要编译哪些模块?

没有。你告诉你想要编译哪些,通常是通过makefile中存在的编译语句。

  

编译器如何识别内部带有main()的模块?

总而言之,这是一个很大的过程,已在this related question中得到解答。

总而言之,在使用标准C库编译程序时,程序的入口点设置为_start。现在,它在内部引用了main()函数。因此,在编译时,没有(需要)检查main()的存在。在链接时,链接器应该能够找到它可以链接到的{strong>一个 main()实例。这样,main()将作为您计划的切入点。

所以,回答

  

编译器如何知道我的主要功能在哪里?

它确实(并且不需要)。这是链接器的工作,特别是。

答案 2 :(得分:0)

启动程序的汇编代码(通常由嵌入式人员称为启动代码)专门调用main()
main()的原型包含在编译器文档中。 编译程序时,会生成目标文件。然后,源代码中的目标文件将与启动运行时组件(通常称为crt0.o [bj])和C库组件等链接。 如果main()更改为无法识别的签名,则编译单元会投诉未解析的_main__main的外部引用。