Utilizzo di goto

di Unqualunque il
7 risposte
Ciao a tutti!
Ho scritto un codice in cui per la prima volta mi sono arreso all'uso di goto.
	char *pStr = pText;

	while( pStr )
	{
		switch( pStr[0] )
		{
			case 'z':

				pStr = ManageCaseZ(pStr);

				if( !pStr )						// Sintax error!
					goto exitReading;

				if( *pStr == '\0' ) 			// End of text.
					goto exitReading;

				break;

			default:
				while(*pStr++ != '\n');		// Skip the line.
				break;
		}

		pStr++;
	}

exitReading:
C'è un modo migliore di fare questa cosa o va bene così?

Paolo

7 Risposte

  • Ad esempio,
    
    	while (pStr)
    	{
    		bool ex = false;
    
    		switch (pStr[0])
    		{
    		case 'z':
    			pStr = ManageCaseZ(pStr);
    
    			if (!pStr) ex = true;
    
    			if (*pStr == '\0') ex = true;
    
    			break;
    		default:
    			while (*pStr++ != '\n');
    			break;
    		}
    
    		if (ex) break;
    
    		pStr++;
    	}
    
    ma occhio al ciclo perché vanno gestite diverse situazioni che si possono presentare ...
  • Bella soluzione, in tal caso scriverei:
    	if (pStr) 
    		if (*pStr == '\0')
    			ex = true;
    	else
    		ex = true;
    per evitare di andare a valutare *pStr == '\0' su un indirizzo nullo.
  • L'utilizzo di goto in linguaggio C non é da demonizzare perché in alcune situazioni può risultare più leggibile delle alternative che lo evitano. Ad esempio per gestire un'uscita comune, in una funzione con diversi punti che potrebbero fallire, si può simulare quello che in linguaggi a più alto livello viene fatto con un try/catch...
    Naturalmente il goto non deve essere utilizzato in sostituzione delle tradizionali strutture di controllo if while ...
  • Sono d'accordo con candaluar, tuttavia non ho mai usato il goto nei miei codici C per coerenza, in modo da usare sempre le stesse tecniche e non dovere avere a che fare con eccezioni difficili da ricordare a lungo termine.
  • Sono tornato a mettere mano a quel codice per altre ragioni, e proprio perché stavo pensando ad altro, ho trovato una soluzione alternativa a questo problema, sostituendo

    if( *pStr == '\0' ) goto exitReading;

    con

    if( *pStr == '\0' ) --pStr;
       char *pStr = pText;
    
       while( *pStr )
       {
          switch( pStr[0] )
          {
             case 'z':
    
                pStr = ManageCaseZ(pStr);
    
                if( !pStr )                  // Sintax error!
                   return NULL;
    
                if( *pStr == '\0' )          // End of text.
                   --pStr;
    
                break;
    
             default:
                _SKIP_LINE(pStr);
                break;
          }
    
          pStr++;
       }
  • Questa soluzione è "debole" nel senso che può avere effetti secondari.

    Se la condizione della while rimane quella attuale, ovviamente funziona, ma se qualcuno per qualsiasi motivo, in seguito modifica quella condizione, avrai, come effetto secondario, che questa soluzione non funzionerà più.

    Quella che ti avevo suggerito invece, continuerà a funzionare.

    Oltre a questo fatto di "robustezza", la soluzione esplicita è più chiara, difficilmente invece un programmatore si rende conto che il decremento del puntatore è collegato all'uscita dal ciclo.
  • Si infatti, è una soluzione debole, necessariamente correlata al contesto: while( *pStr ){ pStr++; }
Devi accedere o registrarti per scrivere nel forum
7 risposte