在重新定义之前从外部作用域访问变量是否定义明确?
Is it well defined to access a variable from an outer scope before it is redefined?
此代码在 gcc-11 中编译时没有警告:
int i{ 2 };
{
std::cout << i; //prints 2
int i{ 3 };
std::cout << i; //prints 3
}
这是定义明确还是恰好有效?
是的,是的。第二个 i
的范围,以及它隐藏第一个 i
的区域,是从它的声明符 (1) 到封闭块。这与无效的原因相同:
{
std::cout << i;
int i{ 3 };
}
但是,当然,这肯定不会发生在任何 你的 代码中,因为作为专业开发人员,你知道最好不要使用 one-character 变量names(2) 除了非常短的循环,或者以混乱的方式重用变量名:-)
(1) 标准(C++20)在[=14中讨论了“声明点”、“潜在范围”和“作用域”的概念=],这是寻找规则的权威场所。
变量名存在于它们的声明点和它们的块结束(它们的潜在范围)之间,不包括它们被遮蔽的区域(遮蔽是潜在和实际范围的差异)。
int i{3}
的声明点实际上位于 i
和 {
之间(在声明之后但在初始化之前)。
这可能会导致一些微妙的问题,例如:
int i = 7;
{
int i {i};
// Value of i here is indeterminate.
}
并且通常足以避免阴影。
(2) 您不会 为变量名称中的每个字符支付 现金,所以最好不要吝啬:-)
Is this well defined or it just happened to work?
是well-defined。在 {...}
块内声明的变量范围从声明点开始,到右大括号结束。来自 this C++17 Draft Standard:
6.3.3 Block scope [basic.scope.block]
1 A name declared in a block (9.3) is local to that
block; it has block scope. Its potential scope begins at its point of
declaration (6.3.2) and ends at the end of its block. A variable
declared at block scope is a local variable.
This code compiles with no warnings in gcc-11
这让我很吃惊。 clang-cl 编译器(在 Visual Studio 2019 中,'borrowing' 来自 MSVC 的 /Wall
开关)给出了这个:
warning : declaration shadows a local variable [-Wshadow]
在 GCC 11.2 中同时使用 -Wall
和 -Wpedantic
不会生成此警告;但是,明确地 添加 -Wshadow
确实可以。不确定 GCC 需要什么“通用”-Wxxx
开关才能显示它。
此代码在 gcc-11 中编译时没有警告:
int i{ 2 };
{
std::cout << i; //prints 2
int i{ 3 };
std::cout << i; //prints 3
}
这是定义明确还是恰好有效?
是的,是的。第二个 i
的范围,以及它隐藏第一个 i
的区域,是从它的声明符 (1) 到封闭块。这与无效的原因相同:
{
std::cout << i;
int i{ 3 };
}
但是,当然,这肯定不会发生在任何 你的 代码中,因为作为专业开发人员,你知道最好不要使用 one-character 变量names(2) 除了非常短的循环,或者以混乱的方式重用变量名:-)
(1) 标准(C++20)在[=14中讨论了“声明点”、“潜在范围”和“作用域”的概念=],这是寻找规则的权威场所。
变量名存在于它们的声明点和它们的块结束(它们的潜在范围)之间,不包括它们被遮蔽的区域(遮蔽是潜在和实际范围的差异)。
int i{3}
的声明点实际上位于 i
和 {
之间(在声明之后但在初始化之前)。
这可能会导致一些微妙的问题,例如:
int i = 7;
{
int i {i};
// Value of i here is indeterminate.
}
并且通常足以避免阴影。
(2) 您不会 为变量名称中的每个字符支付 现金,所以最好不要吝啬:-)
Is this well defined or it just happened to work?
是well-defined。在 {...}
块内声明的变量范围从声明点开始,到右大括号结束。来自 this C++17 Draft Standard:
6.3.3 Block scope [basic.scope.block]
1 A name declared in a block (9.3) is local to that block; it has block scope. Its potential scope begins at its point of declaration (6.3.2) and ends at the end of its block. A variable declared at block scope is a local variable.
This code compiles with no warnings in gcc-11
这让我很吃惊。 clang-cl 编译器(在 Visual Studio 2019 中,'borrowing' 来自 MSVC 的 /Wall
开关)给出了这个:
warning : declaration shadows a local variable [-Wshadow]
在 GCC 11.2 中同时使用 -Wall
和 -Wpedantic
不会生成此警告;但是,明确地 添加 -Wshadow
确实可以。不确定 GCC 需要什么“通用”-Wxxx
开关才能显示它。