a cura di Dario Dariol
 
    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
      • if (i == 7) break Wow
      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.
 




MokaByte®  è un marchio registrato da MokaByte s.r.l.

Java® è un marchio registrato da Sun Microsystems; tutti i diritti riservati

E' vietata la riproduzione anche parziale
Per comunicazioni inviare una mail a
mokainfo@mokabyte.it