提问人:Lumpi 提问时间:2/28/2011 最后编辑:user0118999881999119725 3Lumpi 更新时间:10/11/2012 访问量:122315
调用函数时切换“控制权转移绕过初始化:”
switch "transfer of control bypasses initialization of:" when calling a function
问:
当我尝试构建以下开关时,我收到“控制权转移绕过初始化:”错误:
switch (retrycancel)
{
case 4: //The user pressed RETRY
//Enumerate all visible windows and store handle and caption in "windows"
std::vector<MainHandles::window_data> windows = MainHandles().enum_windows().get_results();
break;
case 2:
//code
}
这与我调用枚举函数有关。如果不允许从交换机内调用函数,是否有解决方法解决此类问题?
答:
127赞
Sam Miller
2/28/2011
#1
C++标准的第 6.6.4 节:
无条件的 goto 语句 将控制权转移到语句 按标识符标记。这 标识符应为标签 (6.1) 位于当前函数中。
C++ 标准的第 6.7 节:
可以转移到 阻止,但不是以绕过的方式 带有初始化的声明。一个 从一个点跳出的程序 其中,具有 automatic 的局部变量 存储持续时间不在 它在范围内的点是 格式不正确,除非变量具有 POD 类型 (3.9),声明时不带 初始 化
强调是我添加的。由于真的是伪装的,所以你遇到了这种行为。要解决此问题,如果必须使用switch
goto
switch
switch (retrycancel)
{
case 4:
{
const std::vector<MainHandles::window_data> windows(
MainHandles().enum_windows().get_results()
);
break;
}
case 2:
//code
}
或重构为if
/else
if (retrycancel == 4) {
const std::vector<MainHandles::window_data> windows(
MainHandles().enum_windows().get_results()
);
} else if (retrycancel == 2)
// code
} else {
...
}
虽然对我来说你希望通过创建内部实现什么并不明显,所以你可能需要重新考虑你的设计。注意我添加了一个限定符,因为它在您的示例中未被修改。windows
vector
switch
const
windows
评论
1赞
Lumpi
3/1/2011
谢谢你的回答,昨天有点晚了,所以我把错误的函数调用复制到开关中,“真实”的更有意义;-)。尽管如此,我还是会使用建议的else if循环。您引用的 c++ 标准的官方来源是什么?
1赞
Sam Miller
3/1/2011
@Lumpi ISO C++ 标准,我前段时间购买了一份。
2赞
tanz
1/6/2015
@SamMiller : 您能否用更简单的术语解释为什么在某些开关情况下需要大括号。我在其中一个开关案例中创建了一个新对象,但是如果我声明或初始化一个普通变量,比如 int,我就会遇到编译器错误。我没有收到任何错误。
0赞
rxantos
5/22/2017
从技术上讲,如果和否则也是伪装的goto。或者,对于那个母体,所有的控制语句都是伪装的goto(因为它们在汇编中转向jmp)。但是,由于您使用的是大括号,因此在大小写语句周围放置大括号的效果相同。
18赞
Armen Tsirunyan
2/28/2011
#2
开关本质上是 ,也就是说,它是相应标签的 a。C++ 标准禁止 goto 绕过非 POD 对象的初始化。将向量声明放入大括号中,它将解决问题goto
goto
switch (retrycancel)
{
case 4: //The user pressed RETRY
{
std::vector<MainHandles::window_data> windows = MainHandles().enum_windows().get_results(); //Enumerate all visible windows and store handle and caption in "windows"
break;
}
case 2:
//code
}
评论
0赞
Lumpi
3/1/2011
谢谢!正如你提到的,这是一个goto,当我试图学习一些正确的编程时,我想我会选择Sam Miller建议的if else if块。
评论