Compilazione condizionale (#ifdef, #ifndef, #else, #endif)

Le direttive del preprocessore sono usate dal compilatore per pre-elaborare il codice sorgente prima di compilarlo. La direttiva inizia sempre con #, quindi il compilatore vieta l'utilizzo del simbolo nei nomi di variabili, funzioni, ecc.

Ogni direttiva è descritta da una voce separata ed è valida fino all'interruzione di riga. Non è possibile utilizzare più direttive in un'unica voce. Se la voce direttiva è troppo grande, può essere suddivisa in più righe usando il simbolo '\'. In questo caso, la riga successiva è considerata una continuazione della voce direttiva.

Direttive di compilazione condizionale del preprocessore permettono la compilazione o il salto di una parte del programma a seconda della realizzazione di una certa condizione.

Tale condizione può assumere una delle seguenti forme.

#ifdef identifier
   // il codice che si trova qui viene compilato se l'identificatore è già stato definito per il preprocessore nella direttiva #define.
#endif

#ifndef identifier
   // il codice che si trova qui viene compilato se l'identificatore non è attualmente definitp dalla direttiva #define del preprocessore.
#endif

Qualsiasi direttiva di compilazione condizionale può essere seguita da un numero qualsiasi di righe eventualmente contenenti la direttiva #else e terminante con #endif. Se la condizione verificata è vera, le righe tra #else ed #endif vengono ignorate. Se la condizione verificata non è soddisfatta, tutte le righe tra il controllo e la direttiva #else (o direttiva #endif se la prima è assente) vengono ignorate.

Esempio:

#ifndef TestMode
   #define TestMode
#endif
//+--------------------------------------------------------------------------------+
//| Funzione di avvio del programma Script                                         |
//+--------------------------------------------------------------------------------+
voidOnStart()
  {
   #ifdef TestMode
      Print("Modalità Test");
   #else
      Print("Modalità Normale");
   #endif
  }

A seconda del tipo di programma e modalità di compilazione, le macro standard sono definite nel seguente modo:

la macro __MQL5__ viene definita quando si compila il file *.mq5, la macro __ MQL4__ viene definita durante la compilazione di un *.mq4.
La macro _DEBUG viene definita durante la compilazione in modalità di debug.
La macro _RELEASE viene definita durante la compilazione in modalità di rilascio.

Esempio:

//+--------------------------------------------------------------------------------+
//| Funzione di avvio del programma Script                                         |
//+--------------------------------------------------------------------------------+
voidOnStart()
  {
   #ifdef __MQL5__
      #ifdef _DEBUG
         Print("Saluti dal compilatore MQL5 [DEBUG]");
      #else
        #ifdef _RELEASE
           Print("Saluti dal compilatore MQL5 [RELEASE]");
        #endif
     #endif
   #else
      #ifdef __MQL4__
         #ifdef _DEBUG
           Print("Saluti dal compilatore MQL4 [DEBUG]");
        #else
           #ifdef _RELEASE
              Print("Saluti dal compilatore MQL4 [RELEASE]");
           #endif
        #endif
     #endif
   #endif
  }