C++ 交叉初始化的标志是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2392655/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What are the signs of crosses initialization?
提问by Jichao
Consider the following code:
考虑以下代码:
#include <iostream>
using namespace std;
int main()
{
int x, y, i;
cin >> x >> y >> i;
switch(i) {
case 1:
// int r = x + y; -- OK
int r = 1; // Failed to Compile
cout << r;
break;
case 2:
r = x - y;
cout << r;
break;
};
}
G++ complains crosses initialization of 'int r'
. My questions are:
G++ 抱怨crosses initialization of 'int r'
。我的问题是:
- What is
crosses initialization
? - Why do the first initializer
x + y
pass the compilation, but the latter failed? - What are the problems of so-called
crosses initialization
?
- 什么是
crosses initialization
? - 为什么第一个初始化器
x + y
编译通过,而后者却失败了? - 所谓的问题是什么
crosses initialization
?
I know I should use brackets to specify the scope of r
, but I want to know why, for example why non-POD could not be defined in a multi-case switch statement.
我知道我应该使用括号来指定 的范围r
,但我想知道为什么,例如为什么不能在多案例 switch 语句中定义非 POD。
回答by avakar
The version with int r = x + y;
won't compile either.
的版本int r = x + y;
也不会编译。
The problem is that it is possible for r
to come to scope without its initializer being executed. The code would compile fine if you removed the initializer completely (i.e. the line would read int r;
).
问题是它有可能在r
没有执行其初始化程序的情况下进入作用域。如果您完全删除初始化程序(即该行将读取int r;
),代码将可以正常编译。
The best thing you can do is to limit the scope of the variable. That way you'll satisfy both the compiler and the reader.
你能做的最好的事情就是限制变量的范围。这样你就会让编译器和读者都满意。
switch(i)
{
case 1:
{
int r = 1;
cout << r;
}
break;
case 2:
{
int r = x - y;
cout << r;
}
break;
};
The Standard says (6.7/3):
标准说 (6.7/3):
It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps from a point where a local variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has POD type (3.9) and is declared without an initializer (8.5).
可以转移到块中,但不能通过初始化绕过声明。从具有自动存储持续时间的局部变量不在范围内的点跳转到它在范围内的点的程序是格式错误的,除非该变量具有 POD 类型 (3.9) 并且声明时没有初始化程序 (8.5)。
回答by Péter T?r?k
You should put the contents of the case
in brackets to give it scope, that way you can declare local variables inside it:
您应该将 的内容case
放在方括号中以赋予它范围,这样您就可以在其中声明局部变量:
switch(i) {
case 1:
{
// int r = x + y; -- OK
int r = 1; // Failed to Compile
cout << r;
}
break;
case 2:
...
break;
};
回答by Ashish Yadav
It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps from a point where a local variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has POD type and is declared without an initializer.
可以转移到块中,但不能通过初始化绕过声明。从具有自动存储持续时间的局部变量不在范围内的点跳转到它在范围内的点的程序是格式错误的,除非该变量具有 POD 类型并且在没有初始化程序的情况下声明。
[Example: Code:
void f()
{
// ...
goto lx; // ill-formed: jump into scope of `a'
// ...
ly:
X a = 1;
// ...
lx:
goto ly; // ok, jump implies destructor
// call for `a' followed by construction
// again immediately following label ly
}
--end example]
The transfer from the condition of a switch statement to a case label is considered a jump in this respect.
从 switch 语句的条件到 case 标签的转移在这方面被认为是一个跳转。
回答by Thomas Matthews
I suggest you promote your r
variable before the switch
statement. If you want to use a variable across the case
blocks, (or the same variable name but different usages), define it before the switch statement:
我建议您r
在switch
声明之前宣传您的变量。如果要跨case
块使用变量(或变量名相同但用法不同),请在 switch 语句之前定义它:
#include <iostream>
using namespace std;
int main()
{
int x, y, i;
cin >> x >> y >> i;
// Define the variable before the switch.
int r;
switch(i) {
case 1:
r = x + y
cout << r;
break;
case 2:
r = x - y;
cout << r;
break;
};
}
One of the benefits is that the compiler does not have to perform local allocation (a.k.a. pushing onto the stack)in each case
block.
好处之一是编译器不必在每个块中执行本地分配(也就是压入堆栈)case
。
A drawback to this approach is when cases "fall" into other cases (i.e. without using break
), as the variable will have a previous value.
这种方法的一个缺点是当案例“落入”其他案例时(即不使用break
),因为变量将具有先前的值。