【问题标题】:C scopes overlap for the same entity?同一实体的 C 范围重叠?
【发布时间】:2015-11-21 15:28:53
【问题描述】:

示例代码如下,'a'都是文件范围:

1 ...
2 int a;
3 int a;
4 ...   // which 'a' is visible?

我知道 'a' 的两个声明是针对同一个对象的。但是每个标识符都有一个范围,两个“a”的范围应该在第 4 行重叠,哪个是可见的?如果第二个 'a' 只可见,是否意味着这种情况如下:

{
    int a;
    {
           int a; // the scope of the first 'a' is hidden
    }
}

谢谢

【问题讨论】:

  • 我遗漏了一些东西,你不能重新定义同一个变量。
  • @terencehill: 1) 在文件范围内,这些是暂定定义,因此首先声明,所以你可以。 2)在嵌套范围内,您可以很好地定义相同的名称。但是正确配置的编译器应该警告在外部范围内隐藏名称。
  • @Olaf 谢谢,我的疑惑只有 1)。

标签: c scope


【解决方案1】:

在文件范围内,类似于

int a;

首先是一个声明。它也是tentative definition。对于同一个名称,您可以根据需要对同一个名称有尽可能多的暂定定义如果它们在技术上是相同的(有关详细信息,请参阅链接)。

但是,如果你添加一个初始化器:

int a = 0;

你有一个(常规的)定义。其中你只能有一个同名。它还必须与所有暂定定义相同。

第二个例子是关于范围的。您可以在不同的范围内使用相同的名称。但是,如果您引用该对象,将使用最里面的名称。无法在外部范围内访问具有相同名称的对象。这称为 shadowing,正确配置的编译器(即启用警告)应该警告它,但允许这样做。

一般来说,这是一种不好的编码风格,因为在阅读代码时必须检查范围才能看到声明。 (这就是编译器应该发出警告的原因)。请注意,内部定义甚至不需要具有相同的类型。

【讨论】:

    【解决方案2】:

    套用this answer

    在全局范围内,您编写的内容可以正常工作(它会在函数范围内引发错误)。也就是说,假设您编写以下内容:

    int a;
    int a;
    int main(...){...}
    

    这将编译得很好,但只是因为a 都没有被初始化。如果你多次声明一个赋值,事情就会中断。这是一个例子:

    int a;
    int a;      // No problem yet
    int a = 10; // a is now initialized
    int a = 12; // Error: Redefinition of a
    

    前两个定义(以及您给出的那种)是所谓的暂定定义。 C规范说其中多个被视为冗余。重要的是每个都有零个或一个初始化定义。

    最后,回答你的问题:

    ...
    int a;
    int a;
    ...   // which 'a' is visible?
    

    我的理解是答案是两者都,因为它们是同一个变量的暂定定义。

    【讨论】:

    • a = 11; 的行是语句,没有声明符;它在文件范围内无效。抱歉,当我写第一个(现已删除)评论时,我没有阅读整个答案。或许你应该专注于declarationtentative definition和(常规)definition的区别;这将使事情更容易理解。
    • 我的错误。固定的。我还会补充一些关于这些差异的内容。
    猜你喜欢
    • 2018-05-02
    • 1970-01-01
    • 2010-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    相关资源
    最近更新 更多