【问题标题】:Why is creating a variable using 'extern' a declaration and not a definition?为什么使用“extern”创建变量是声明而不是定义?
【发布时间】:2012-07-16 15:26:06
【问题描述】:

我在阅读时遇到了以下问题......只是无法理解这背后的逻辑。

auto int c;
static int c;
register int c;
extern int c;

前面三个是定义,最后一个是声明,怎么来的?

【问题讨论】:

  • 为什么投反对票?这是本论坛的一个有效问题。
  • 四个都是声明。前三个也是定义。
  • @Blank - 这是一个愚蠢的问题。 extern 表示在其他地方定义。为什么这不是一个定义?
  • 傻只是意味着你知道答案...

标签: c declaration definition


【解决方案1】:

带有extern 的最后一个没有为c 定义存储。它仅表明c 存在于某处,链接器应该能够将其解析为在其他地方定义的某个全局c

如果您编译并链接了单个 .c 文件并尝试使用最后一个 c,则会出现链接器错误。对于前 3 个cs,您不会因为它们在当前编译单元中有实质内容(它们已被定义)。

如果您想了解更多关于 extern 和声明与定义的信息,请点击此处的 good article。引用那篇文章:

变量/函数的声明只是声明变量/函数存在于程序中的某处,但没有为它们分配内存

【讨论】:

    【解决方案2】:

    关键字extern 引用了变量(或可能是函数)的定义在别处的事实;然后编译器将此声明链接到单独文件中定义的主体。前面的三个关键字声明了一个声明——变量没有在别处定义,因此不是prototypes

    例如,假设您有这样的项目结构:

    ..
    -- main.c
    -- client.c
    -- client.h
    -- server.c
    -- server.h
    

    gcc 使用头文件编译这些时,头文件通常将define 程序所需的变量。这会分配一个链接到 .c 文件中符号的declaration 的符号。这就是编译器将各种项目文件与.o 对象链接起来的方式。通过使用objdump -d(假设您在 Linux 上)调试程序的实际反汇编结构,您可能会对这一切如何显示更感兴趣。

    祝你好运!

    【讨论】:

      【解决方案3】:

      前 3 个语句实际上为 int 分配了一个位置。

      最后一个没有。它告诉编译器的只是在另一个编译单元的某个地方,将定义一个名为 cint

      如果未定义,稍后会出现链接器错误。不出所料,链接器会说 c 未定义。

      【讨论】:

        【解决方案4】:

        前三个是定义,因为它将为变量留出存储空间。

        最后一个不会为int c 分配任何存储空间。它只会使用在别处分配和命名的存储空间。

        【讨论】:

          【解决方案5】:

          四句是声明,前三句也是定义。

          阅读here 了解声明和定义之间的区别。

          autostaticregister 是变量的修饰符。阅读有关它们的文档。

          extern 只是声明,因为您告诉编译器变量或函数的定义在其他地方 - 在另一个 C 模块中 -。

          希望对你有帮助!

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-10-22
            • 1970-01-01
            • 1970-01-01
            • 2019-11-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多