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.

È stato utile?

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
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top