C:使用"ld"分别编译和链接组件程序?



我试图理解extern和链接。作为一个简单的演示,我编写了两个C文件:一个使用函数的主文件和另一个定义函数的文件:

/* main.c */
#include <stdio.h>
extern void print_nos(int, int);
int main(void) {
print_nos(10, 20);
return 0;
}
/* print_nos.c */
#include <stdio.h>
void print_nos(int lower, int higher) {
int i;
for (i = lower; i <= higher; i++)
printf("%d ", i);
printf("n");
}

我有两个问题:

1)

我知道我可以简单地将这两个文件作为参数同时传递给gcc:

gcc -o main main.c print_nos.c

这工作得很好,但我想使用ld显式地进行链接,所以我这样做了:

$ gcc -c main.c        # produces main.o
$ gcc -c print_nos.c   # produces print_nos.o
$ ld -o main main.o print_nos.o -lc
ld: warning: cannot find entry symbol _start; defaulting to 0000000000401050

可以看到,我得到了上面的警告,当我尝试运行输出文件时:

$ ./main
-bash: ./main: No such file or directory

我没有太多的汇编经验,所以我不知道从哪里开始解决这个问题-任何帮助都是感激的。

2)

其次,当我删除extern指示符并尝试运行gcc -o main.c print_nos.c时,程序编译得很好。一个函数需要被声明为extern吗?当我窥视到所有的标准包含文件,如stdlib, stdio等,我看到所有的函数都有一个extern声明。因此,我是否应该在我的情况下使用extern(在类似于上面的实际代码中)?

我不建议直接使用ld,除非你知道你在做什么并且有一个很好的理由。如果您想单独编译模块(这是一个好主意,这样您就可以只重新编译源文件已更改的模块),您可以使用gcc来完成编译和链接,如下所示:

gcc -c main.c        # produces main.o
gcc -c print_nos.c   # produces print_nos.o
gcc -o main main.o print_nos.o

对于extern说明符,函数不需要它。函数声明默认是隐式的extern

最新更新