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

Fir*_*ser 1 c linker extern

我正在尝试理解extern和联系。作为一个简单的演示,我编写了两个 C 文件:一个使用函数的主文件和另一个定义该函数的文件:

/* main.c */
#include <stdio.h>
extern void print_nos(int, int);
int main(void) {
    print_nos(10, 20);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)
/* 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");
}
Run Code Online (Sandbox Code Playgroud)

我有两个与此相关的问题:

1)

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

gcc -o main main.c print_nos.c
Run Code Online (Sandbox Code Playgroud)

这工作正常,但我想使用显式进行链接ld,所以我这样做了:

/* main.c */
#include <stdio.h>
extern void print_nos(int, int);
int main(void) {
    print_nos(10, 20);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如您所见,当我尝试运行输出文件时,我收到上述警告:

$ ./main
-bash: ./main: No such file or directory
Run Code Online (Sandbox Code Playgroud)

我在组装方面没有太多经验,所以我不知道从哪里开始解决这个问题 - 任何帮助都是值得赞赏的。

2)

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

sj9*_*126 5

我不建议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
Run Code Online (Sandbox Code Playgroud)

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