我正在开发一个包含多个模块(源文件,头文件,库)的项目。所有汤中的一个文件包含我的主要功能。
我的问题是:
答案 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
的外部引用。