模块内部的调用:由编译器或链接器解决?

时间:2014-08-19 13:04:48

标签: c compilation linker

如果调用函数f()并在同一个c文件(模块)中实现 - 谁解决了这个调用?编译器或链接器?

2 个答案:

答案 0 :(得分:2)

我认为它在技术上依赖于实现,但通常编译器会解析同一文件中的引用。由于编译器知道正在调用哪个函数,因此在链接时间之前没有必要推迟它,如果编译器不必离开某个地方,它可以更有效地生成函数调用的代码用于链接器填写地址。 (例如,它可能能够使用具有16位偏移的相对跳转指令来调用附近的函数,而不是使用嵌入在代码中的32位或64位地址的绝对跳转。)< / p>

如果被调用函数被声明为weak symbol,这可能会改变:在这种情况下,虽然函数是在当前转换单元中定义的,但是该定义可能会在链接时被另一个模块覆盖,所以编译器必须将其视为对另一个模块中函数的调用。

答案 1 :(得分:1)

这取决于符号的联系。如果f是一个内部函数,例如那些用 static 声明/定义的函数,那么f将在编译中解析(由编译器完成)。如果fweak symbol,那么它将在动态链接中解析(通过动态加载程序)。如果f是一个强符号,则在编译时(由编译器)解析它。

特别是,当程序使用优化进行编译时,f可以直接内联到调用者的主体中,这由编译器完成。