L'indizio qui è che il codice base è molto vecchio.
Questo trucco probabilmente esiste perché il codice una volta era stato portato su un compilatore con alcuni molto vecchi preprocessore che non tratta indefiniti macro come 0 in preprocessore #if
condizionali.
Vale a dire, come del 1989 ANSI C è stato standardizzato che se abbiamo:
#if foo + bar - xyzzy
la direttiva è soggetta alla sostituzione macro, in modo che se foo
, bar
o xyzzy
sono macro, vengono sostituiti. Quindi tutti gli identificatori rimanenti che non sono stati sostituiti vengono sostituiti con 0
. Quindi, se foo
è definito come 42
, ma bar
e xyzzy
non sono definiti a tutti, otteniamo:
#if 42 + 0 - 0
e non, per esempio, cattiva sintassi:
#if 42 + -
o qualche altro comportamento, come la diagnostica circa bar
non definito.
Su un preprocessore in cui le macro non definite vengono considerate vuote, #if SOMETHING_SUPPORTED
si espande a solo #if
, che è quindi errato.
Questo è l'unico modo in cui questo trucco IDENT+0
ha senso. Semplicemente non vorrai mai farlo se puoi contare sul fatto che la pre-elaborazione sia conforme ISO C.
La ragione è che se si prevede che SOMETHING_SUPPORTED
abbia valori numerici, è erroneamente disperso per definirlo semplicemente come uno spazio vuoto. Idealmente vuoi rilevare quando è successo e interrompere la compilazione con una diagnostica.
In secondo luogo, se il tuo do supporta un tale uso spregevole, quasi certamente vuoi un simbolo esplicitamente definito, ma vuoto comportarsi come se avesse il valore 1, non il valore 0. Altrimenti, sei creando una trappola. Qualcuno potrebbe farlo sulla riga di comando del compilatore:
-DSOMETHING_SUPPORTED=$SHELL_VAR # oops, SHELL_VAR expanded to nothing
o nel codice:
#define SOMETHING_SUPPORTED /* oops, forgot "1" */
Nessuno sta andando a aggiungere un #define
o -D
per un simbolo con l'intento di trasformare off la funzionalità che controlla! Il programmatore che inserisce un #define SOMETHING_SUPPORTED
senza 1
sarà sorpresa dal comportamento di
#if SOMETHING_SUPPORTED+0
che salta il materiale che doveva essere abilitato.
Questo è il motivo per cui sospetto che pochi programmatori C leggendo questo abbiano mai visto un tale utilizzo e perché sospetto che sia solo una soluzione per il comportamento del preprocessore il cui effetto voluto è saltare il blocco se manca SOMETHING_SUPPORTED
. Il fatto che si tratti di una "trappola programmatore" è solo un effetto collaterale della soluzione alternativa.
Per risolvere tale problema preprocessore senza creare una trappola programmatore è quello di avere, da qualche parte nelle prime fasi l'unità di traduzione, questo:
#ifndef SOMETHING_SUPPORTED
#define SOMETHING_SUPPORTED 0
#endif
e poi altrove basta usare #if SOMETHING_SUPPORTED
.Forse quell'approccio non si presentava al programmatore originale, o forse quel programmatore pensava che lo stratagemma +0
fosse pulito, e avesse dato valore al suo autocontenimento.
Potrebbe essere correlato: [Test per definizione macro vuota] (http://stackoverflow.com/questions/4102351/test-for-empty-macro-definition) –
Il '! = 0' è sicuramente ridondante –