In C e C ++, quali metodi possono prevenire l'uso accidentale del compito (=) laddove è necessaria l'equivalenza (==)?

15

In C e C ++, è molto facile scrivere il seguente codice con un errore grave.

char responseChar = getchar();
int confirmExit = 'y' == tolower(responseChar);
if (confirmExit = 1)
{
    exit(0);
}

L'errore è che l'istruzione if avrebbe dovuto essere:

if (confirmExit == 1)

Come codificato, uscirà ogni volta, perché si verifica l'assegnazione della variabile confirmExit , quindi confirmExit viene utilizzato come risultato dell'espressione.

Ci sono buoni modi per prevenire questo tipo di errore?

    
posta DeveloperDon 25.08.2012 - 08:28
fonte

7 risposte

59

La tecnica migliore è di aumentare il livello di avviso del compilatore. Ti avviserà quindi del potenziale incarico in caso di condizionale.

Assicurati di compilare il tuo codice con zero avvisi (che dovresti comunque fare). Se vuoi essere pedante, imposta il compilatore per trattare gli avvertimenti come errori.

Usare i condizionali Yoda (mettendo la costante sul lato sinistro) era un'altra tecnica che era popolare circa dieci anni fa. Ma rendono il codice più difficile da leggere (e quindi mantengono a causa del modo innaturale che leggono (a meno che tu non sia Yoda)) e non offrono alcun beneficio maggiore dell'aumento del livello di avviso (che ha anche ulteriori vantaggi di più avvertimenti).

Gli avvisi sono errori logici nel codice e dovrebbero essere corretti.

    
risposta data 25.08.2012 - 08:51
fonte
9

Potresti sempre fare qualcosa di radicale come testare il tuo software. Non intendo nemmeno test unitari automatizzati, solo i test che ogni singolo sviluppatore esperto fa per abitudine eseguendo il suo nuovo codice due volte, una volta confermata l'uscita e una volta no. Questo è il motivo per cui la maggior parte dei programmatori lo considera un non-problema.

    
risposta data 25.08.2012 - 18:42
fonte
6

Un modo tradizionale per impedire l'uso scorretto dei compiti all'interno dell'espressione è posizionare la costante a sinistra e la variabile a destra.

if (confirmExit = 1)  // Unsafe

if (1=confirmExit)    // Safe and detected at compile time.

Il compilatore segnalerà un errore relativo all'assegnazione illegale a una costante simile alla seguente.

.\confirmExit\main.cpp:15: error: C2106: '=' : left operand must be l-value

La condizione revisionata if sarebbe:

  if (1==confirmExit)    

Come mostrato dai commenti seguenti, questo è considerato da molti un metodo inappropriato.

    
risposta data 25.08.2012 - 08:28
fonte
4

Sono d'accordo con tutti dicendo "avvisi del compilatore", ma voglio aggiungere un'altra tecnica: recensioni del codice. Se hai una politica di revisione di tutto il codice che viene eseguito, preferibilmente prima che venga eseguito il commit, è probabile che questo tipo di problemi venga rilevato durante la revisione.

    
risposta data 26.08.2012 - 23:14
fonte
2

Innanzitutto, aumentare i livelli di avviso non fa mai male.

Se non vuoi che il tuo condizionale verifichi il risultato di un compito all'interno dell'istruzione if stessa, dopo aver lavorato con molti programmatori C e C ++ nel corso degli anni, e non aver mai sentito che confrontare il costante prima if(1 == val) era una brutta cosa, potevi provare questo costrutto.

Se il leader del tuo progetto approva ciò che fai, non preoccuparti di cosa pensano gli altri. La vera prova è se tu o qualcun altro puoi dare un senso al tuo codice mesi e anni a partire da ora.

Se intendevi testare il risultato di un incarico, tuttavia, l'uso di avvisi più elevati potrebbe [probabilmente avrebbe] catturato l'assegnazione a una costante.

    
risposta data 27.08.2012 - 00:08
fonte
1

In ritardo verso la festa come sempre, ma l'analisi del codice statico è la chiave qui

La maggior parte degli IDE ora fornisce SCA oltre al controllo sintattico del compilatore e sono disponibili altri strumenti, inclusi quelli che implementano le linee guida MISRA (*) e / o CERT-C.

Dichiarazione: faccio parte del gruppo di lavoro MISRA C, ma sto pubblicando a titolo personale. Sono anche indipendente da qualsiasi venditore di strumenti

    
risposta data 06.11.2012 - 12:54
fonte
-2

Usa l'assegnazione della mano sinistra, gli avvertimenti del compilatore possono aiutarti, ma devi assicurarti di ottenere il livello giusto altrimenti sarai sommerso da avvertimenti inutili o non ti verranno indicati quelli che vuoi vedere.

    
risposta data 07.11.2012 - 10:26
fonte

Leggi altre domande sui tag