#define, #ifdef #undef #endif
-
05-07-2019 - |
Domanda
Ho il seguente codice
#define PROC_ADD
void main(void)
{
while(1)
{
#ifdef PROC_ADD
// Do this code here then undefined it to run the code in the else
// processing work
#undef PROC_ADD
#else
// now that PROC_ADD has been undefined run this code
// processing work
#endif
}
}
Tuttavia, eseguirà il codice. Ma non eseguirà il codice in else
dopo che PROC_ADD
non è stato definito.
Penso che il motivo potrebbe essere che puoi definire e annullare la definizione solo in fase di compilazione e non in fase di esecuzione. Tuttavia, non ne sono davvero sicuro.
Soluzione
Quello che stai facendo è l'equivalente del tempo di costruzione di:
int x = 1;
int main()
{
if (x)
{
...
x = 0;
}
else
{
...
}
}
ifdef, ecc. si verificano al momento della creazione, ma per il tuo esempio non è un problema. Dopo aver valutato if (il modulo runtime o build-time), è stata presa la decisione su quale ramo prendere. Cambiare qualcosa dopo che la decisione è stata presa non cambia quella decisione.
Altri suggerimenti
La condizione ifdef
viene valutata quando arriva il preprocessore. Quando undef
PROC_ADD
all'interno del codice ifdef
'', il preprocessore ha già deciso quale sezione di codice includere e quali ignorare.
Inoltre, sì: ifdef
, undef
, ecc. vengono elaborati in fase di pre-elaborazione - il compilatore non vede nemmeno queste cosiddette direttive. Questo ovviamente significa che il codice di runtime non vede neanche queste direttive.
Modifica : il preprocessore funziona eseguendo un singolo passaggio nel file di testo. Al preprocessore non importa nemmeno che il tuo file di testo contenga codice C! Non ha conoscenza del fatto che i tuoi ifdef
e else
e che cosa non accade all'interno di un ciclo while
.
#define
funziona solo durante la preelaborazione. Quindi
#define PROC_ADD
void main(void)
{
#ifdef PROC_ADD
// Do this code here then undefined it to run the code in the else
// processing work
#undef PROC_ADD
#else
// now that PROC_ADD has been undefined run this code
// processing work
#endif
}
verrà elaborato nel modo seguente: poiché PROC_ADDR
è definito, il preprocessore escluderà completamente il ramo #else
e quindi eseguirà #undef
, quindi il codice di ramo #else
non sopravvive mai alla preelaborazione e non raggiunge mai il compilatore.
In quasi tutti i linguaggi di programmazione o sintassi, una volta che l'esecuzione è entrata in un ramo di un condizionale (in questo caso, il condizionale è #ifdef
, anche se la condizione cambia durante l'esecuzione del ramo, altri rami non verranno mai eseguiti.
Sono sicuro che non ti aspetteresti che questo stampi " Ciao " ;, vuoi?
if (i == 1)
i = 0;
else
printf("Hello\n");
Fondamentalmente quello che stai dicendo è che il codice nel ramo else
dovrebbe sempre essere eseguito, quindi estrarlo da un ramo e inserirlo direttamente nel codice .
Sia il compilatore che l'esecuzione eseguono un solo passaggio attraverso i condizionali, una volta trovata una corrispondenza non guardano oltre.
Quindi vuoi eseguire il codice rappresentato dalla seconda sezione dei commenti sempre ? Perché non farlo
#ifdef PROC_ADD
// Do the stuff to be done if PROC_ADD is defined
#undef PROC_ADD
#endif
// Do the stuff to always be done
modifica
OK: se si desidera modificare il comportamento in fase di esecuzione, è necessario utilizzare costrutti in fase di esecuzione (come una variabile che funga da flag). Come diciamo tutti;), le direttive pre-processore vengono valutate una sola volta, al momento della compilazione.
Pensaci in questo modo: else
parte del seguente codice non viene eseguita anche se x
è stato impostato su false
in < code> if .
La condizione è verificata nella riga if (x)
stessa - una volta inserito quel blocco, non ricalcola ciascuna delle sezioni successive else
- il compilatore ha ha già preso una decisione al riguardo.
bool x = true;
if(x)
{
//do something
x = false;
}
else
{
//else code
}