unreachable traduction statement significa que java if-statement unreachable-code unreachable-statement

traduction - ¿Por qué un compilador de Java no produce un error de declaración inalcanzable para una declaración entonces inalcanzable?



unreachable statement java que significa (5)

Si trato de compilar

for(;;) { } System.out.println("End");

El compilador de Java produce un error que dice Unreachable statement . Pero si agrego otra declaración de break " inalcanzable " (según yo) y la hago:

for(;;) { if(false) break; } System.out.println("End");

Se compila. ¿Por qué no produce un error?


Básicamente, el código inalcanzable se detecta analizando el programa de forma estática sin ejecutar realmente el código. Mientras que la condición se verificará en tiempo de ejecución . Entonces, cuando se lleva a cabo este análisis, en realidad no tiene en cuenta la condición, sino que simplemente verifica ese break; es accesible ( accesible ) a través de if .


Como se explicó en mi respuesta a una pregunta similar , la construcción específica if(compile-time-false) está exenta de las reglas de inalcanzabilidad como una puerta trasera explícita. En este caso, el compilador trata su break como accesible debido a eso.


De la JLS

Una instrucción if-then puede completarse normalmente si al menos uno de los siguientes es verdadero:

> La instrucción if-then es accesible y la expresión de condición no es una expresión constante cuyo valor es verdadero.

> La instrucción then puede completarse normalmente.

Entonces, if(false) está permitido.

Esta capacidad de "compilar condicionalmente" tiene un impacto significativo y una relación con la compatibilidad binaria. Si se compila un conjunto de clases que usan dicha variable "flag" y se omite el código condicional, no es suficiente distribuir solo una nueva versión de la clase o interfaz que contenga la definición del flag. Un cambio en el valor de un indicador no es, por lo tanto, compatible con los binarios preexistentes. (También hay otras razones para tal incompatibilidad, como el uso de constantes en las etiquetas de caso en las declaraciones de cambio;)


El comportamiento se define en la descripción JLS de declaraciones inalcanzables :

La declaración then es accesible si la declaración if-then es accesible.

Por lo tanto, el compilador determina que la instrucción then ( break; ) es accesible, independientemente de la condición en el if .

Y un poco más, énfasis mío:

Un enunciado básico for puede completarse normalmente si al menos uno de los siguientes es verdadero:

  • La declaración for es accesible, hay una expresión de condición, y la expresión de condición no es una expresión constante (§15.28) con valor verdadero.
  • Hay una declaración de break accesible que sale de la declaración for.

Por lo tanto, el for puede completarse normalmente porque la instrucción then contiene un break . Como notó, no funcionaría si reemplazara el break con el return .

La justificación se explica hacia el final de la sección. En sustancia, if tiene un tratamiento especial para permitir construcciones como:

if(DEBUG) { ... }

donde DEBUG puede ser una constante de tiempo de compilación.


La razón principal por la que Java no detecta todas las declaraciones inalcanzables es que generalmente es imposible responder si el código es accesible o no. Esto se deduce del hecho de que el problema de detención es indecidible sobre las máquinas Turing.

Entonces, está claro que no se pueden detectar todas las declaraciones inalcanzables, pero ¿por qué no intentar evaluar las condiciones? Imagine ahora que la condición utilizada no es solo false sino algo así como ~x == x . Por ejemplo, todas estas declaraciones se imprimirán true para cada int x ( source ).

System.out.println((x + x & 1) == 0); System.out.println((x + -x & 1) == 0); System.out.println((-x & 1) == (x & 1)); System.out.println(((-x ^ x) & 1) == 0); System.out.println((x * 0x80 & 0x56) == 0); System.out.println((x << 1 ^ 0x1765) != 0);

Las declaraciones pueden ser bastante complicadas; lleva tiempo resolverlos. Aumentaría significativamente el tiempo de compilación y, después de todo, no detectará todas las declaraciones inalcanzables. El compilador fue diseñado para tomar algunos esfuerzos pero no gastar demasiado tiempo para eso.

La única pregunta que queda es: ¿dónde dejar de resolver las condiciones? Las razones para eso no parecen tener justificación matemática y se basan en el escenario de uso. JLS-14.21 explica los motivos de su caso particular.