2

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

主程序

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

交流

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

公元前

#include <stdio.h>

void a()
{
   printf("func a in b\n");
}
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   

我的问题是:

  • 为什么amain函数中调用函数a in b.c而不是a in a.c
  • 更改 library order:gcc main.c libb.a liba.a后,结果是一样的。为什么?
  • 为什么链接器在这种情况下不报告符号冲突?
4

2 回答 2

1

a没有bmain.c. 如果这样做,在将其传递给链接器之前,您会从编译器获得多个声明错误。你一定做错了什么main.c

于 2013-09-01T05:42:21.040 回答
1

在传递给链接器的选项中,按照目标文件出现的顺序(从左到右)搜索目标文件以查找要解析的符号。

假设已运行以下内容以准备链接:

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

链接器执行以下操作:

main.o需要a()b ()。首先liba是搜索:a()找到,b()不是。所以其次libb是搜索。b()找到了,但也是另一个 a()导致上面显示的链接器错误。

如果这样做:

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

没有给出错误main并被创建。

链接器执行以下操作:

main.o需要a()b ()。First libbis searched: a()and b()are 被找到。由于没有什么要解决的,甚至没有查看/查看。libb liba

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

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

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

于 2013-09-01T09:24:55.067 回答