我已经分叉了一个C ++项目并在交换机中添加了一些案例。然后它会跳到下一个案例的中间。条件为int
,案例值为#define
d。由于代码很大,我在这里写的东西相当简单:
#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
,它会在评论中跳到同一个地方!每个案例都以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;
}
在调试会话或正常执行中,Everything编译良好并执行相同的操作。我在Eclipse CDT Indigo下使用gcc 4.5.4。
它看起来像编译器错误,但可能是什么原因?
答案 0 :(得分:0)
如果您通过调试器单步执行该函数,则调试器中的“当前突出显示的行”不一定与当前正在执行的行相对应(涉及循环时,启用优化时,有大量宏时等) )。
在切换后将变量打印到stdout / stderr并查看它们的值是否正确。同时在cases
内的stdout / stderr中打印一些调试行。如果得到的输出是正确的,请不要担心奇怪的代码执行顺序。
示例:
#define AAA 1
#define BBB 2
int X::func(int i) {
bool b = (i == 5);
int v = (b ? 10 : 5);
std::cout << "before switch/case" << std::endl;
switch (i) {
case AAA:
std::cout << "AAA, before if block" << std::endl;
if (b && v > 4) {
v = v + 1;
std::cout << "within AAA if block" << std::endl;
return 0;
}
std::cout << "AAA, after if block" << std::endl;
break;
case BBB:
std::cout << "BBB, before if block" << std::endl;
if (!b || v > 40) {
v = v + 2;
b = false; // direct jump here from the switch for i = AAA
std::cout << "BBB, within if block" << std::endl;
return 0;
}
std::cout << "BBB, after if block" << std::endl;
break;
}
std::cout << "after switch/case" << std::endl;
return -1;
}
- 编辑 -
如果为case语句添加{}括号,可能会有所帮助:
case AAA:{
break;
}
如果你将案件中的东西转移到单独的函数中,它肯定会有所帮助。这不会改进代码,但调试器肯定能够完成它们。
答案 1 :(得分:0)
我已经建立了一个&#34;克隆&#34;项目(project_test)来自原始项目(项目)。在预构建步骤中,我有一个复制所有源文件的rsync(重点是不复制autotools的东西):
rsync -a --exclude=tests/* --exclude=perf/* --exclude=tools/* --include=*/ --include=*.[ch] --include=*.[ch]pp --exclude=* ${workspace_loc:/project}/ ${workspace_loc:/project_test}/ && cp ${workspace_loc:/project}/tests/one_with_main.cpp ${workspace_loc:/project_test}/tests/
它构建良好,调试正如预期的那样。
替代方案可以是rsync -a --delete
,而不是rsync -a
。