背景:
在提出质询前,我想指出,我已查过以下连结:
Identify loops in java byte code
我可以检测字节码(类文件)中的循环,使用基于控制流图(graph)的基于控制分析算法的后边缘检测方法。
我的问题:
在检测到循环之后,您可能最终会有两个循环(由两个不同的后边缘定义)共享相同的循环头。这可以通过以下两种情况来创建:(案例1)在源代码中,您有一个for或while循环,并有一个连续语句;(例2)在源代码中,您有两个循环--一个是do-while和一个内循环的外循环;这些循环之间没有指令。
我的问题是:只看字节码,如何区分这两种情况?
我的想法:
在do-while循环中(即没有任何继续语句),您不会期望返回到循环头的go-to语句,换句话说,创建一个后边缘。
在一段时间或一段时间内(也就是没有任何继续语句),似乎可以有一个go-to语句(我不确定是否有必须是一个)。我的编译器生成(我使用的是标准的1.7编译器)这条转到循环之外的指令,而不是像给定链接中提到的那样作为后边缘(这个go-to语句创建了一个到循环头的控制流,但不是从循环的末尾跳回来)。
因此,我的猜测是,(重复,在两个后边的情况下),如果其中一个是由go-to语句创建的后边缘,那么源代码中只有一个循环,它包括一个连续语句(案例1)。否则,源代码中有两个循环(例2)。
谢谢。
发布于 2016-10-26 12:03:09
当两个循环等价时,你所能做的就是取最简单的一个。
没有办法区分while (true),do { } while (true)和for (;;)
如果您有do { something(); } while (false),那么这个循环可能根本不会出现在字节码中。
发布于 2016-10-26 14:22:08
作为Peter Lawrey already pointed out,无法通过查看字节码来确定源代码形式。要给出一个更接近您意图的示例,请使用以下单循环代码
do action(); while(condition1() || condition2());生成与嵌套循环完全相同的代码。
do do action(); while(condition1()); while(condition2());同样,下面的循环
do {
action();
if(condition1()) continue;
break;
} while(condition2());生成的代码与
do action(); while(condition1() && condition2());使用当前的javac,但令人惊讶的是
do {
action();
if(!condition1()) break;
} while(condition2());它只显示了确切的表单在多大程度上依赖于编译器内部。下一个版本的javac可能会对它们进行不同的编译。
https://stackoverflow.com/questions/40261531
复制相似问题