【问题标题】:Why can function defined in a different file access variables defined in that file without extern?为什么定义在不同文件中的函数可以访问该文件中定义的变量而无需 extern?
【发布时间】:2014-05-08 18:25:18
【问题描述】:

我有两个文件:main.c 和 main1.c:

main1.c:

#include <stdio.h>

int a = 12;

void foo(void)
{
    printf("%d\n", a);
}

main.c

#include <stdio.h>
#include <stdlib.h>

void foo(void);

int main(void)
{
    foo();
}

即使变量 'a' 没有在 main.c 中定义并且没有用 extern 声明,为什么 foo() 会打印 12?在用 extern 声明之前,我不能在 main.c 中使用“a”变量。这是否意味着当函数被调用时,它以某种方式“继承”在定义它的翻译单元中定义的所有变量?我知道链接概念(或者我认为我知道),我想知道这里发生了什么。

【问题讨论】:

    标签: c extern linkage


    【解决方案1】:

    foo 的实现可以访问a。 main.c 中foo 的声明并没有规定它的实现可以访问什么。

    【讨论】:

      【解决方案2】:

      编译器的作用是将每个.c文件转换成一个'object'文件。为此,它认为每个 .c 文件都是相对独立的。

      编译 main.c 和 main1.c 时,编译器一次只关注其中一个。

      当编译器专注于编译 main.c 时,不考虑 main1.c 及其内容。

      当编译器专注于编译 main1.c 时也是如此; main.c 及其内容不予考虑。

      因此,这两个 .c 文件是完全隔离编译的(彼此之间)。

      生成的“目标”文件包含机器代码、导出的符号列表、“未解析的符号”列表以及其他内容。


      链接器的功能是打包构成可执行文件的所有“目标”文件,并解析每个“目标”文件中列出的“未解析符号”。

      是链接器建立连接,例如,在“main1”对象文件导出的函数“foo()”和“main”对象所需的“未解析的外部”“foo()”之间文件。

      为了更正确,main.c 中的行:

      void foo(void);
      

      应该改成:

      extern void foo(void);
      

      由于 'main.c' 是与 'main1.c' 隔离编译的,并且由于 'main.c' 没有引用 'a',因此编译器会报告错误。

      Why can function defined in a different file access variables defined in that file without extern?

      变量 'a' 在 main1 对象内部;因此可以完全访问 main1 中的引用。

      其实是'main'不能访问'a'。没有某种“extern int a”引用来告知编译器“a”的特征,并且链接器将负责解析“a”的实际位置。

      Why does foo() print 12 even if variable 'a' is not defined in main.c?

      变量“a”与“main.c”无关。它仅“存在于” main1.c 中。不需要在'main.c'中定义值。

      Does it mean that when the function is called it somehow 'inherits' all variables defined in translation unit where it's defined?

      没有。 (术语“继承”更多地与“面向对象”环境有关。术语“继承”在 C 中很少使用)。

      【讨论】:

        猜你喜欢
        • 2011-07-29
        • 2019-10-06
        • 2012-05-26
        • 1970-01-01
        • 2012-04-25
        • 1970-01-01
        • 2020-05-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多