【发布时间】:2013-09-13 13:04:02
【问题描述】:
我已经分叉了一个 C++ 项目并在 switch 中添加了一些案例。然后它跳到下一个案例的中间。条件为int,案例值为#defined。由于代码比较大,我这里写一个等价的简单的东西:
#define AAA 1
#define BBB 2
int X::func(int i) {
bool b = (i == 5);
int v = (b ? 10 : 5);
switch (i) {
case AAA:
if (b && v > 4) {
v = v + 1;
return 0;
}
break;
case BBB:
if (!b || v > 40) {
v = v + 2;
b = false; // direct jump here from the switch for i = AAA
return 0;
}
break;
}
return -1;
}
如果我将 AAA 传递给 X::func,代码执行会直接从 BBB 案例中的 switch 跳转到 b = false;。在真实的代码中,我有几十个案例,而且它发生在中间。如果我完全评论case BBB,它会跳到 cmets 的同一个地方!每个案例都以break; 结尾,并且内部没有变量声明。就像这里的变量 b 和 v 一样,它们是在 switch 语句之前声明的。
部分案例位于#ifdef #endif 块中。出现问题的其他情况在此块中。条件为真,因此编译该块。反正我把这两条预编译语句都打了之后测试了一下,还是一样的。
如果我添加括号{} 以完全包含这里的情况,我仍然有相同的结果:
case BBB: {
if (!b || v > 40) {
v = v + 2;
b = false; // direct jump here from the switch for i = AAA
return 0;
}
break;
}
无论是在调试会话中还是在正常执行中,一切都可以正常编译并执行相同的操作。我在 Eclipse CDT Indigo 下使用 gcc 4.5.4。
它看起来像一个编译器错误,但可能是什么原因?
【问题讨论】:
-
这个“等效”代码是否也有同样的问题?
-
您是否有机会在启用优化的情况下进行调试?
-
它跳转到 cmets 中的同一个位置的事实告诉我,您实际上并没有调试您的“最新版本”。请注意,优化的发布代码可以在没有任何方法的情况下疯狂地跳来跳去(是的,我知道这不是真的,但你们编译器编写者有一些非常有趣的想法,比如模块间优化
)。很少,很少,不再存在编译器错误 - 这并不是说它们没有,而是 1000 个中有 999 个,“编译器错误”代码实际上正在按照您的要求执行(我很惊讶它是如何做到的) !) :-D -
让您的案例和条件更简单。您的“等效”代码看起来很乱。如果“部分案例在#ifdef #endif 块中。”,这只会使事情变得更糟。
-
等待对 doctorlove 评论的回复...如果“等效”代码没有同样的问题,那也无济于事。您可能没有看到派生代码中不存在的某些因素(实际上这是最可能的情况)。没有看到这个因素,我们就无法知道出了什么问题。提供的任何代码绝对应该重现该问题。
标签: c++ gcc compiler-construction switch-statement case