c语言 - gcc 链接静态库中未解析符号的顺序是什么



在调试函数符号冲突问题时,我发现gcc的一个奇怪行为我无法理解,下面的示例代码举例说明:

main.c

#include <stdio.h>
int  main()
{
   b();
   a();
}

a.c

#include <stdio.h>
void  a(void)
{
   printf("func a in an");
}

b.c

#include <stdio.h>
void a()
{
   printf("func a in bn");
}
void b()
{
  printf( "func b try to call a  n");
  a();
}

编译:

gcc -c a.c
gcc -c b.c
ar -cr liba.a a.o
ar -cr libb.a b.o
gcc main.c liba.a libb.a

执行:

./a.out
func b try to call a  
func a in b
func a in b   

我的问题是:

  • 为什么在main函数中调用函数aa in b.c而不是a in a.c
  • 更改库顺序:gcc main.c libb.a liba.a后,结果相同。为什么
  • 为什么链接器在这种情况下不报告符号冲突

在传递给链接器的选项中,按对象文件的出现顺序从左到右搜索要解析的符号。

假设在准备链接时运行了以下内容:

gcc -c main.c
gcc -c a.c
gcc -c b.c
ar -cr liba.a a.o
ar -cr libb.a b.o

然后这个

gcc -o main main.o liba.a libb.a

将产生:

libb.a(b.o): In function `a':
b.c:(.text+0x0): multiple definition of `a'
liba.a(a.o):a.c:(.text+0x0): first defined here
collect2: ld returned 1 exit status

链接器执行以下操作:

CCD_ 6需要CCD_ 7和CCD_。搜索第一个liba:找到了a(),没有找到b()。其次搜索CCD_ 12。发现了b(),但也另一个a()导致了上面显示的链接器错误。

如果进行:

gcc -o main main.o libb.a liba.a

没有给出任何错误,并且创建了main

链接器执行以下操作:

CCD_ 16需要CCD_ 17和CCD_。搜索第一个libb:找到a()b()。由于没有任何问题需要解决,libbliba甚至没有被查看。

在后一种情况下,程序(main)的输出为:

func b try to call a  
func a in b
func a in b

对于main.oliba.alibb.a的所有其他可能排列,链接器将做什么/显示什么,留给读者练习。;-)

main.c中没有包含ab函数声明。如果您这样做,您将从编译器获得多个声明错误,然后再将其传递给链接器。你一定在main.c中做错了什么。

相关内容

  • 没有找到相关文章

最新更新