【问题标题】:extern with global definition of variable in c外部变量在c中的全局定义
【发布时间】:2013-03-24 12:59:02
【问题描述】:

我有以下我感兴趣的源代码。

#include <stdio.h>
extern int foo;
int foo = 32;

int main()
{
printf("%d", foo);
}

这是一段完全正常的代码,当我用它编译时

gcc -Wall -Wextra -pedantic foo.c

我没有收到任何警告。

这看起来很奇怪,因为变量在同一个文件中既定义为外部变量,又定义为全局变量。 我很确定链接器很容易在同一个文件中找到外部变量的引用,但它看起来不像是编码错误吗?如果是这样,为什么编译器不对此发出警告?

【问题讨论】:

    标签: c gcc global-variables extern


    【解决方案1】:

    没有什么奇怪的。您首先声明了一个变量(您向编译器承诺它存在),然后您实际定义了它。没有问题。

    此外,默认情况下,所有非函数本地变量且未定义为 static 的变量都是 extern

    【讨论】:

    • 先声明然后定义也可以在函数定义中看到,如:void function(int n; char d[n], int n);我正确吗
    • @GrijeshChauhan 正确。这是允许从较小的单独编译的部分(目标文件和库)创建程序的机制。代码和数据可能分散在多个文件中。
    • 非常感谢您说“所有不是函数本地且未定义为静态的变量都是外部变量”。我的假设正好相反,想弄清楚如何使 C 中定义的变量标签对汇编程序可见,这让我很头疼。
    【解决方案2】:

    您似乎误解了extern 的作用。 extern 只是让你的声明只是一个声明而不是一个定义。

    int i; //definition of i
    extern int i; //declaration of i
    

    对同一个变量有多个声明是完全正常的,但整个程序中应该只存在一个定义。将此与函数进行比较

    void f(void); //declaration
    void f(void) //definition(and redeclaration)
    {
    } //definition
    

    为了使用一个变量或函数,你只需要它的声明。它的定义可能出现在程序的任何地方(链接器会找到它)。任何地方都可以是同一个文件、另一个文件,甚至是外部库。

    【讨论】:

      【解决方案3】:

      这似乎很奇怪,因为一个变量在同一个文件中既定义为外部变量,又定义为全局变量。

      extern int foo;
      

      说:它声明时没有定义类型为 int 的对象,名为 foo

       int foo = 32;
      

      它声明并定义了一个类型为int 的对象,名为foo,带有外部链接。

      没有矛盾,它是有效的 C 代码。

      【讨论】:

      • 但如果 foo 确实在其他文件中声明(如 extern 所承诺的),则代码 int foo = 32; 将不正确。
      • @Armin: foo 可以在任意多个文件中声明任意多次(有或没有extern),但初始化不能超过一个。
      • @teppic 并非没有extern。在翻译单元结束时,暂定定义将成为实际定义。具有相同名称的外部对象的多个定义是未定义的行为。
      • @ouah - 如果您在一个文件中有int foo; 而在另一个文件中有int foo;,那很好。
      • @teppic 这是未定义的行为。两个暂定定义都将在各自翻译单元的末尾成为真正的定义。而 C99 在 6.9p5 中说:“如果在表达式中使用了通过外部链接声明的标识符 [...],则在整个程序的某处,该标识符应恰好有一个 extern one 外部定义;否则,应不超过一个。”
      【解决方案4】:

      不同之处在于前者是一个声明 -> extern 声明一个变量并说它可以在附近的某个地方使用。您可以拥有任意数量的声明,而后者是一个必须恰好存在一次的定义。
      所以应该没有警告也没有错误。

      【讨论】:

        【解决方案5】:

        extern 是一种为在别处定义的变量提供可见性的方法...

        extern 就像一个承诺...

        在example.h中

        extern int g;// promises that this will be in the object code to anything that includes example.h
        

        例子。 c

        int g;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-10-01
          • 2012-06-18
          • 2011-07-13
          • 1970-01-01
          相关资源
          最近更新 更多