与类型同名的变量放在函数、结构或 class 中时不会出现编译错误

Variable with same name as type gives no compilation error when placed in function, struct or class

给定代码:

#include <iostream>

typedef int Integer;
Integer Integer = 1234;

int main() {
    std::cout <<  "Integer: " << Integer;
}

gcc 11.2 Compiler编译代码会出现编译错误:

error: 'Integer Integer' redeclared as different kind of entity
    4 | Integer Integer = 1234;
      |         ^~~~~~~

note: previous declaration 'typedef int Integer'
    3 | typedef int Integer;
      |             ^~~~~~~

In function 'int main()':
error: expected primary-expression before ';' token
    7 |         std::cout <<  "Integer: " << Integer;
      |                                             ^

但是,将代码更改为:

#include <iostream>

typedef int Integer;

int main() {
    Integer Integer = 1234;
    std::cout <<  "Integer: " << Integer;
}

不会导致编译错误。
我尝试使用 gcc 11.2, clang 12.0.1 和 MSVC 19.29 编译器,第一个版本都失败了,但允许第二个版本。
为什么第二个版本有效而​​第一个版本失败?

区别在于范围之一。

在第一个示例中,两个 Integer 都在全局范围内声明:

typedef int Integer;
Integer Integer = 1234;

在第二个例子中,一个是在全局范围内声明的,而另一个是局部的 main:

typedef int Integer;
int main() {
    Integer Integer = 1234;
    ...
}

之所以有效,是因为在编译器读取 main 中的第一个 Integer 时,只有一个实体具有该名称,因此它必须引用全局范围内的类型。但是一旦你在 main 中声明了一个名为 Integer 的变量,你就不能再次使用该名称来引用该类型:

typedef int Integer;
int main() {
    Integer Integer = 1234; // OK because only the type is visible.
    Integer otherInteger = 567; // Error because Integer is a variable here.
    ::Integer thirdInteger = 89; // OK because :: resolves to the global one.
}