【问题标题】:redefinition of variable inside scope在范围内重新定义变量
【发布时间】:2015-11-03 09:43:01
【问题描述】:
为什么以下代码在 g++ 下编译时没有任何警告或错误?
我看到的问题是第一行中定义的变量 x 可以在 if 范围内访问,但尽管它再次被重新定义。
int main() {
int x = 5;
std::cout << x;
if (true) {
int x = 6;
std::cout << x;
}
}
【问题讨论】:
标签:
c++
compiler-errors
g++
【解决方案1】:
根据C-
C99 中的 6.2.1:
如果声明标识符的声明符或类型说明符出现在块内或函数定义中的参数声明列表内,则标识符具有块作用域,其终止于关闭关联块的 }
...
如果一个词法相同标识符的外部声明存在于同一个名称空间中,它会被隐藏,直到当前作用域终止,之后它再次变得可见。
在 C 和 C++ 中,在多个范围内使用同一个名称是合法的。
因此,在您的代码中,之前的 i 一直隐藏,直到 if 语句的范围终止。
【解决方案2】:
C++ 标准允许名称隐藏,这意味着您可以在嵌套范围内声明具有相同标识符的任何内容。
来自N4296:
3.3.10 名称隐藏 [basic.scope.hiding]
- 可以通过在嵌套声明区域或派生类中显式声明相同名称来隐藏名称。
- 类名 (9.1) 或枚举名 (7.2) 可以通过在
相同的范围。如果一个类或枚举名称和一个变量,数据
成员、函数或枚举器在同一范围内声明(在任何
order) 同名,隐藏类名或枚举名
变量、数据成员、函数或枚举器名称在哪里
可见。
- 在成员函数定义中,块范围内的名称声明隐藏了具有相同名称的类成员的声明
姓名;见 3.3.7。派生类中成员的声明
(第 10 条)隐藏基类成员的声明
一样的名字;见 10.2。
- 在查找由命名空间名称限定的名称期间,本来可以通过 using 指令可见的声明
可以被命名空间中同名的声明隐藏
包含使用指令;见 (3.4.3.2)。
- 如果名称在范围内且未隐藏,则称其为可见
列表中的 1 项是您需要的。
【解决方案3】:
您用于在代码最后一行打印的x 属于if 块。这个x 隐藏了第一行中声明的第一个x。这是因为范围。
int main() {
int x = 5; //Accessble throughout the main.
std::cout << x;
if (true) {
int x = 6; //Local to this if block. Not accessible outside if block
std::cout << x; //Prints local x's value
}
}
【解决方案4】:
第二个x 变量有一个块作用域,它遮蔽了前面的x 声明。