Domanda

Un Cliente recentemente eseguito l'analisi statica del codice di base C del mio datore di lavoro e ci ha dato i risultati. Tra le patch utili è stata la richiesta di cambiare il famoso do { ... } while(0) macro do { ... } while(0,0). Capisco che cosa il loro cerotto sta facendo (utilizzando l'operatore sequenza per ritorno valutare il valore del secondo "0", quindi l'effetto è lo stesso), ma non è chiaro il motivo per cui avevano favoriscono la seconda formare sopra la prima forma.

C'è un motivo legittimo per cui si dovrebbe preferire la seconda forma della macro, o sia l'analisi statica dei nostri clienti di essere eccessivamente pedante?

È stato utile?

Soluzione

Beh, io andrò per una risposta:

  

C'è un motivo legittimo per cui si dovrebbe preferire la seconda forma della macro ...?

No. Non v'è alcun motivo legittimo. Entrambi valutare sempre false, e qualsiasi compilatore decente probabilmente girare la seconda nella prima nell'assemblea comunque. Se ci fosse alcuna ragione per essere valida in alcuni casi, C è stato in giro per molto tempo sufficiente per questo motivo di essere scoperto dai maggiori guru di me.

Se vi piace il vostro codice di fare gli occhi di gufo-y su di te, utilizzare while(0,0). In caso contrario, utilizzare quello che usa il resto del mondo della programmazione C e dire strumento di analisi statica del vostro cliente per spingerlo.

Altri suggerimenti

Solo una supposizione sul motivo per cui si potrebbe suggerire utilizzando

do { ... } while(0,0)

su

do { ... } while(0)

Anche se non c'è alcuna differenza comportamento e dovrebbe essere alcuna differenza di costo di esecuzione tra i due.

La mia ipotesi è che lo strumento di analisi statica si lamenta il ciclo while essere controllato da una costante nel caso più semplice e non lo fa quando si utilizza 0,0. Il suggerimento del cliente è probabilmente solo in modo da non ottengono un sacco di falsi positivi dallo strumento.

Per esempio io di tanto in tanto venire in situazioni in cui voglio avere un'istruzione condizionale controllato da una costante, ma il compilatore si lamenta con un avvertimento circa un'espressione condizionale valutazione ad una costante. Poi devo passare attraverso alcuni cerchi di ottenere il compilatore di smettere di lamentarsi (dato che non piace avere avvertimenti spurie).

Il tuo suggerimento di cliente è uno dei cerchi che ho usato per calmare questo avvertimento, anche se nel mio caso non è stato controlla un ciclo while, era a che fare con un'affermazione "fallisce sempre". Di tanto in tanto, avrò una superficie di codice che non dovrebbe mai eseguire (forse il caso di default di un interruttore). In quella situazione potrei avere un'affermazione che non riesce sempre con qualche messaggio:

assert( !"We should have never gotten here, dammit...");

Ma, almeno un compilatore che uso emette un avvertimento circa l'espressione valutando sempre false. Tuttavia, se cambio a:

assert( ("We should have never gotten here, dammit...", 0));

L'avvertimento va via, e tutti felici. Sto indovinando che strumento di analisi statica del cliente anche la vostra sarebbe, troppo. Si noti che ho generalmente nascondo quel po 'di cerchio salto dietro una macro come:

#define ASSERT_FAIL( x) assert( ((x), 0))

Potrebbe essere bello essere in grado di dire al venditore di strumento per risolvere il problema, ma ci potrebbe essere casi legittimi in cui in realtà non vogliono diagnosticare un ciclo di essere controllato da un'espressione booleana costante. Per non parlare del fatto che anche se convincere un venditore strumento per fare un tale cambiamento, che non ti aiutano per il prossimo anno o giù di lì che potrebbe prendere per ottenere effettivamente una correzione.

Uso while(0,0) impedisce Microsoft compilatore di generare un avviso di una condizione che è una costante (Warning C4127).

Quando questo avviso è abilitato (ad esempio con / W4 o / parete), si può essere spento su un caso per caso con questo simpatico piccolo trucco ( vedere questo altro thread ).

EDIT: Dal momento che Visual Studio 2017 15.3, while(0) non emette più avvertenze (cfr Constant condizionali ). Si può sbarazzarsi del vostro (0,0)!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top