如何解决以下代码中语句的执行是否被编译器优化改变了?
在一个 recent related 问题中,我发现以下代码
public static void main(String[] args) {
/*1*/ int x;
/*2*/ boolean found = false;
/*3*/ if (!found)
/*4*/ x = -1;
/*5*/ System.out.println(x);
}
有编译器错误,即 x 不是 init.(初始化)。我很惊讶编译器无法对 init.d 进行推理。特别是因为这段代码似乎不需要任何运行时推理,如下所示:
- 在指示的第 2 行,
found
设置为false
。 - 第 2 行和第 3 行之间没有代码。
- 因此到达第 3 行,
!found
必然是true
,因此 init 是不可避免的。
我想知道这是否正确。我依稀记得编译器优化可以改变语句的执行顺序。这在这里起作用吗?是否有可能在第 3 行和第 4 行之前到达第 5 行?
环境
openjdk 15.0.2 2021-01-19
OpenJDK 运行时环境(构建 15.0.2+7-27)
OpenJDK 64 位服务器 VM(构建 15.0.2+7-27,混合模式,共享)
javac 15.0.2
视窗 10
解决方法
看我的(迟到的)answer on the other question。源代码分析是规范要求的。
这不是按照您建议的方式重新排序代码的情况;这会改变行为,这是被禁止的。
想想一般情况:如果在计算完成之前允许使用计算,那么没有什么是可预测的。
但是,在您的示例中,允许足够智能的编译器将生成的代码优化为(有效)System.out.println(-1)
。这两个变量实际上都不是必需的。
如果发生这样的事情,它不会影响确定分配所需的检查。逻辑上,简化发生在验证源代码之后。
您必须检查生成的字节码以了解实际发生的情况。此外,在 Java 中,优化可以“稍后”通过即时编译为本机代码来完成。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。