当 if 条件为常量时,为啥未检测到无法访问的代码?

Posted

技术标签:

【中文标题】当 if 条件为常量时,为啥未检测到无法访问的代码?【英文标题】:Why isn't unreachable code detected when an if condition is a constant?当 if 条件为常量时,为什么未检测到无法访问的代码? 【发布时间】:2020-04-29 12:17:21 【问题描述】:

我正在准备 Java 考试,遇到了“unreachable statement”编译器错误,例如:

Source.java:10: error: unreachable statement
       System.out.println("This code is not reachable");

我试图了解何时会或不会发生这种情况 - 例如。它不会在这些情况下发生:

// Case #1
if (true) 
    System.out.println("This code is reachable");
 else 
    System.out.println("This code is not reachable"); // Compiles OK


// Case #2
for (i = 0; i < 5; i++) 
    if (true) continue;
    System.out.println("This code is not reachable"); // Compiles OK

编译器似乎不够聪明,无法检测if 条件何时始终为true - 有人可以提供更详细的解释吗?

【问题讨论】:

分析似乎是complete but unsound,因此它可能会遗漏错误,但它确实给出的错误绝不是错误的。这是分析的设计选择。 【参考方案1】:

来自 Java 语言规范,14.21. Unreachable Statements(我强调):

如果一个语句不能被执行,这是一个编译时错误,因为 无法访问。

本节专门对这个词进行精确解释 “可达。”这个想法是必须有一些可能的执行 从构造函数、方法、实例开始的路径 初始化程序或静态初始化程序,其中包含对 声明本身。分析考虑了结构 陈述。 whiledofor的特殊处理除外 条件表达式具有常量值 true 的语句,则 流分析中不考虑表达式的值

因此,虽然代码确实不可访问,但编译器明确不认为它如此。说明的原因是允许程序员定义“标志”变量,例如

static final boolean DEBUG = false;

if (DEBUG)  x=3; 

应该可以在falsetrue 之间切换DEBUG,而无需更改代码中的任何其他内容(由于编译错误)。

【讨论】:

以上是关于当 if 条件为常量时,为啥未检测到无法访问的代码?的主要内容,如果未能解决你的问题,请参考以下文章

C语言 (条件编译#ifdef#ifndef) (#if 常量,#if 1,#if 0)的用法

将数组转换为向量,我得到了一些未检测到的错误

装Kingbase ES V7时为啥依赖检测时,总是提示我说Microsoft Visual C++ 2008未通过检测???

为啥在 LibreOffice Calc 中未正确检测到单元格增量

为啥执行某些命令后 Pexpect 会间歇性挂起(未检测到 EOF)?

js基础⑤