编译器优化是否改变了以下代码中语句的执行?
Is the execution of statements in the following code changed by compiler optimization?
在一个问题中我发现下面的代码
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.(initialized) 的编译器错误。我很惊讶编译器无法推理 init.特别是因为这段代码似乎不需要任何运行时推理,如下所示:
- 在指示的第 2 行,
found
设置为 false
。
- 第 2 行和第 3 行之间没有代码。
- 所以到了第3行,
!found
必然是true
所以init是必然的
我想知道这是否正确。我依稀记得编译器优化可以改变语句的执行顺序。这在这里起作用吗?是否有可能在第 3 行和第 4 行之前到达第 5 行?
环境
openjdk 15.0.2 2021-01-19
OpenJDK 运行时环境 (build 15.0.2+7-27)
OpenJDK 64 位服务器 VM(build 15.0.2+7-27,混合模式,共享)
javac 15.0.2
Windows10
看看我的(晚)。规范要求源代码分析。
这不是按照您建议的方式重新排序代码的情况;这会改变行为,这是被禁止的。
想想一般情况:如果在计算完成之前允许使用计算,那么没有什么是可预测的。
但是,在您此处的示例中,允许足够智能的编译器将生成的代码优化为(有效地)System.out.println(-1)
。这两个变量实际上都不是必需的。
如果发生这样的事情,不会影响对definite assignment的必要检查。从逻辑上讲,简化发生在验证源代码之后。
您必须检查生成的字节码才能了解实际发生的情况。此外,在 Java 中,可以通过实时编译为本机代码来完成优化 'later'。
在一个
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.(initialized) 的编译器错误。我很惊讶编译器无法推理 init.特别是因为这段代码似乎不需要任何运行时推理,如下所示:
- 在指示的第 2 行,
found
设置为false
。 - 第 2 行和第 3 行之间没有代码。
- 所以到了第3行,
!found
必然是true
所以init是必然的
我想知道这是否正确。我依稀记得编译器优化可以改变语句的执行顺序。这在这里起作用吗?是否有可能在第 3 行和第 4 行之前到达第 5 行?
环境
openjdk 15.0.2 2021-01-19
OpenJDK 运行时环境 (build 15.0.2+7-27)
OpenJDK 64 位服务器 VM(build 15.0.2+7-27,混合模式,共享)
javac 15.0.2
Windows10
看看我的(晚)
这不是按照您建议的方式重新排序代码的情况;这会改变行为,这是被禁止的。
想想一般情况:如果在计算完成之前允许使用计算,那么没有什么是可预测的。
但是,在您此处的示例中,允许足够智能的编译器将生成的代码优化为(有效地)System.out.println(-1)
。这两个变量实际上都不是必需的。
如果发生这样的事情,不会影响对definite assignment的必要检查。从逻辑上讲,简化发生在验证源代码之后。
您必须检查生成的字节码才能了解实际发生的情况。此外,在 Java 中,可以通过实时编译为本机代码来完成优化 'later'。