【问题标题】:C linker not behaving as expected [duplicate]C链接器未按预期运行[重复]
【发布时间】:2018-06-06 07:15:58
【问题描述】:

我有两个 C 文件 9.c ,10.c.

9.c

#include <stdio.h>
int b=6;
int main()
{
fun1();
printf("%d\n",b);
}
extern int b;

10.c

void fun1()
{
printf("%d\n",b);
b=8;
}

我做了 gcc 9.c 10.c 但它给出了以下错误:

10.c:3: error: 'b' undeclared (第一次在这个函数中使用)

我原以为链接器会解析 b 的定义,但为什么它没有解析。

【问题讨论】:

  • 那不是链接器在抱怨,那是编译器。你还没有在10.c 中声明b
  • 链接只是编译过程的一部分,编译过程分为四个阶段:1)预处理2)编译3)汇编4)链接
  • 编译器错误

标签: c


【解决方案1】:

9.c 结尾处的extern int b; 行应该位于 10.c 开头。这告诉编译器 b 的声明在另一个模块中。见How to correctly use the extern keyword in C

更新 回复您的评论以及上面的 cmets:当其他人说此错误来自编译器而不是链接器时,他们专门指的是构建过程的“编译”阶段。在这个阶段,每个源文件都是独立处理的。因此,您在 9.c 中声明 b 的事实并不能帮助编译器在 10.c 中识别它。如果您想将此标识符的解析延迟到链接阶段,您需要在 10.c 中声明变量的extern,因为这是缺少声明的地方。

在 9.c 中声明 extern 是没有意义的,因为实际的声明出现在同一个文件的前面。

我怀疑你在想extern 好像它的意思是“导出”,即告诉编译器记住b 在9.c 中声明的命令,以便它可以解析其他文件中对它的引用.这不是它的意思。它是一条命令,告诉编译器这个变量是在当前源文件外部定义的;所以你将它包含在每个源文件中,其中引用了在别处声明的变量。 (或者更典型的是,它用于包含在此类源文件中的头文件中,例如stdio.h。)

【讨论】:

  • @user3290550 - 因为问题出在 9.c,而不是 10.c。 C 文件是独立编译的。
  • @OliverCharlesworth , 10.c 出现编译错误,请参考问题。
  • @user3290550 - 嗯,没错。那么你不能在声明之后使用它们。
  • @user3290550。请参阅更新的答案。重点不是 extern 不能在文件的最后一行,重点是在这种情况下它需要在 10.c 中,在对 b 的引用之前,它不需要在 9 .c 。
  • @Dave Costa,它非常有用,我只有一个疑问,当我们不包含 stdio.h 并使用 printf 时,编译器如何确保有可用的 printf 定义。
猜你喜欢
  • 2017-10-23
  • 1970-01-01
  • 2021-04-08
  • 1970-01-01
  • 2021-07-23
  • 1970-01-01
  • 1970-01-01
  • 2021-03-23
  • 2014-10-02
相关资源
最近更新 更多