|
|
Soluzione
Esercizio 009 - Goto
Facendo riferimento a questo semplice programma:
class
Quiz9{
public static void main(String [] args){
int i = 1;
Wow:
System.out.println("A i="+i);
Wow:
try {
Here:
i++;
System.out.println("B i="+i);
Here:
for(i=3; i<10; i++) {
if (i%2 == 0)
continue Here;
if (i == 7)
break Wow;
if (i > 7)
break Here;
System.out.println("C i="+i);
}
Here:
System.out.println("D i="+i);
break Wow;
} finally {
Here:
System.out.println("E i="+i);
return;
}
Wow:
System.out.println("F i="+i);
}
}
avevo provocatoriamente chiesto:
Prima
domanda
-
Il (vostro)
compilatore Java compila questo programma senza errori e/o warning?
Il lettore attento avra' ovviamente notato
che nell'unico metodo main ci sono ben 4 label eguali a Here
e 3 label eguali a Wow.
E' legale avere piu' label eguali fra di loro in uno stesso metodo Java?
La risposta e' si' e no:
-
Si' se le label si riferiscono (cioe' etichettano)
statement Java diversi tra di loro (come nell'esempio sopra fornito),
-
No se le stesse label si riferiscono a statement
Java annidati tra loro
Per essere piu' precisi la specifica
di Java afferma:
The scope of a label declared by a labeled statement
is the statement immediately enclosed by the labeled statement.
...
It is a compile-time error if a label shadows
the declaration of another label immediately enclosed in the enclosing
method.
Ad esempio e' illegale (e quindi il nostro
compilatore Java lo segnala come errore) il seguente frammento di codice:
...
Here:
// A legal
for (i=0; i<10; i++) {
System.out.println("i="+i);
Here: // B illegal
for (j=0; j<i; j++) {
System.out.println("j="+j);
if (j == m)
continue Here; // A or B?
if (j == n)
continue Here; // A or B?
...
}
if (i == n)
continue Here; // A
...
}
Here:
// C legal
...
che dovrebbe essere riscritto in questo modo:
...
Here:
// A legal
for (i=0; i<10; i++) {
System.out.println("i="+i);
Other: // B legal
for (j=0; j<i; j++) {
System.out.println("j="+j);
if (j == m)
continue Here; // A
if (j == n)
continue Other; // B
...
}
if (i == n)
continue Here; // A
...
}
Here:
// C legal
...
Quindi la risposta alla prima domanda e' che il nostro
compilatore non segnala errori o warning. Se questo compartamento sia corretto
lo vedremo comunque con la risposta alla quarta domanda.
Seconda
domanda
-
Nel caso
ci siano degli errori di compilazione quali righe del programma vanno modificate
o cancellate?
Nessuna
modifica al nostro programma, perche' il nostro
compilatore non segnala nessun errore (ma leggi comunque la risposta alla
quarta
domanda).
Terza
domanda
-
Quando
si esegue il programma: cosa stampa?
Stampa
i numeri primi inferiori a 10:
A
i=1
B
i=2
C
i=3
C
i=5
E
i=7
Ma un'analisi
piu' accurata dovrebbe essere fatta su quali statement di stampa (identificati
dalle lettere A-F) vengano eseguiti a run-time. Notiamo che non sono mai
eseguiti gli statement identificati da D e F:
-
D non
e' mai eseguito perche' nel ciclo for
che lo precede lo statement
fa terminare
il try
block identificato da Wow.
-
F non
e' mai eseguito perche' segue un try
block con una clausola finally
dove al suo interno viene eseguito un return.
Quindi F e' quello che si chiama unreachable statement (vedi la definizione
di Unreachable Statement nella specifica di Java).
Quarta
domanda
-
Alla luce
di quanto stampato dal programma: cosa pensate del sistema di diagnostica
del (vostro) compilatore Java?
L'analisi
fatta a conclusione della risposta della terza domanda
mostra che F e' un unreachable statement. La specifica di Java richiede
che:
It
is a compile-time error if a statement cannot be executed because it is
unreachable.
Quindi
la dignostica del nostro
compilatore Java non ci soddisfa pienamente. Ci saremmo aspettati un bell'errore,
simile a quello che lo stesso nostro
compilatore fornisce quando tenta di compilare qualcosa del tipo:
boolean
negative(int n){
return n<0;
System.out.println("n ="+n);
}
Siamo
quindi un po' delusi dal nostro
compilatore, ma non amareggiamoci troppo: il nostro
compilatore segue pedantemente la specifica di Java per quanto riguarda
gli statement unreachable e questa specifica non e' del tutto corretta.
Infatti il nostro esempio rispecchia un errore nella specifica gia' notato
e segnalato in questa
pagina di Java Spec
Report (un sito che raccoglie, in maniera non ufficiale, circa un centinaio
di errata riguardanti le specifiche di Java).
Il
nostro compilatore
Esistono
molti compilatori Java attualmente sul mercato. Io ho provato gli esempi
citati in questo articolo con due compilatori:
Se qualcuno
dei miei pochi lettori usa un compilatore che segnala un errore compilando
l'esempio fornito in questo quiz me lo faccia sapere contattandomi via
email: avro' infatti piacere di citare in questa sede tutti i compilatori
abbastanza smart che segnalano gli unreachable statements che trovano.
|
|
|
|