【问题标题】:In C,why is multiple declarations working fine for a global variable but not for a local variable?在 C 中,为什么多个声明对全局变量有效,但对局部变量无效?
【发布时间】:2023-03-12 18:19:01
【问题描述】:

在下面的代码中,为什么多个声明(和一个定义)对于全局变量 x 可以正常工作,但对于 main() 函数内部的局部变量 y 却不行?它显示以下 2 个错误:

1) 重新声明没有链接的“y”

2) 之前的 'y' 声明在这里

为什么局部变量显示错误,全局变量却没有?不仅是我的书,而且来自该论坛的以下 2 个链接清楚地表明我们可以多次声明一个变量(尽管只定义一次)。

link1 link2

请注意解释第一个错误“没有链接的'y'的重新声明”的“没有链接”部分是什么意思?什么联系以及与谁联系?局部变量会链接到哪里?

    #include<stdio.h>

    int x;
    int x;
    int x=303;

    int main(void)
    {

      int y;
      int y;
      int y=776;   //Works fine if above 2 declarations are removed!!

      printf("The value of x is %d,and of y is %d",x,y);

    }

【问题讨论】:

  • 阅读en.wikipedia.org/wiki/Linker_%28computing%29 了解链接和链接器。还有莱文的书iecc.com/linker;所以局部变量没有链接(因为它们在本地调用框架中,在堆栈上)。
  • 但它在我的编译器中也显示 x 错误。
  • @Jeyamaran 您可能一直在使用 C++ 编译器。这是一道 C 题。

标签: c


【解决方案1】:

在 C 和 C++ 中,int y;在函数内既是声明又是定义。

在 C 中,文件范围(在任何函数之外)中的int x; 是一个声明和一个暂定定义。允许多个暂定定义;只允许一个定义

【讨论】:

  • 看来你中了靶心。等一下,看看别人怎么说。
  • 当然。当我们在这里时,另一个有趣的事情是作用域如何影响变量名:stackoverflow.com/questions/2393458/…
  • @maditya:如果我在函数(本地范围)中声明和定义一个变量而不使用它怎么办?仍然分配内存?但是在全局范围的情况下,只有在使用时才分配内存?
  • extern 的用法也只意味着声明?那么“extern int x=10;”的用法呢? ?它是否有效并且即使不使用也分配内存?
  • 暂定定义是定义。只要所有(或只有一个)都是暂定的,您就可以有多个定义。你在最后一句中的意思是只允许一个带有初始化器的定义。
【解决方案2】:

这是 C99 标准第 6.2.2 节第 2 部分中定义的方式:

在构成整个程序的一组翻译单元和库中,每个 具有外部链接的特定标识符的声明表示相同的对象或 功能。在一个翻译单元中,每个标识符的声明都带有内部 链接表示相同的对象或功能。每个标识符的声明都没有 链接表示一个唯一的实体。

“全局”变量x 具有外部链接,因此它们表示同一个对象。而本地的y 变量没有链接,所以会发生冲突。

参考:C99 Standard

【讨论】:

    【解决方案3】:

    对于外部变量,任何不是初始化的声明都是暂定定义。这些本身不会创建任何存储,因此允许多个存储。以你为例:

    int x;      // tentative def
    int x;      // and again -- ok
    int x=303;  // definition -- ok
    int x=303;  // multiple definition -- error
    

    如果文件末尾只有暂定定义,则变量定义一次,并设置为 0。

    这意味着如果您链接到另一个也具有x 暂定定义的文件,根据标准,您将遇到错误。不过,大多数编译器/链接器始终允许这样做,并且在标准中将其定义为扩展。

    对于局部变量,由于范围规则,每个声明都是一个定义。但是,这是允许的:

    void func(void)
    {
       int y = 0;
       {
          int y = 1;   // a completely different y
       }
    }
    

    【讨论】:

    • "这意味着如果您链接到另一个也具有 x 的暂定定义的文件,根据标准,您将遇到错误。"我试过这个,但没有错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-17
    • 2019-06-12
    • 2014-02-12
    • 2011-11-25
    相关资源
    最近更新 更多