Условная компиляция (#ifdef, #ifndef, #else, #endif)

Директивы препроцессора используются компилятором для предварительной обработки исходного кода перед его компиляцией. Директива всегда начинается со знака # (решетка), поэтому компилятор запрещает использовать данный символ в именах переменных, функций и т.д.

Каждая директива описывается отдельной записью и действует до переноса строки. Нельзя в одной записи использовать несколько директив. Если запись директивы получается слишком большой, то её можно разбить на несколько строк с помощью обратного слеша '\', в таком случае следующая строка будет считаться продолжением записи директивы.

Директивы условной компиляции препроцессора позволяют компилировать или пропускать часть программы в зависимости от выполнения некоторого условия.

Условие может принимать одну из описываемых ниже форм.

#ifdef identifier
   // код, находящийся здесь, компилируется, если identifier уже был определен для препроцессора в команде #define.
#endif
#ifndef identifier
   // код, находящийся здесь, компилируется, если identifier в данный момент не определен командой препроцессора #define.
#endif

За любой из команд условной компиляции может следовать произвольное число строк, содержащих, возможно, команду вида #else и заканчивающихся #endif. Если проверяемое условие справедливо, то строки между #else и #endif игнорируются. Если же проверяемое условие не выполняется, то игнорируются все строки между проверкой и командой #else, а если ее нет, то командой #endif.

Пример:

#ifndef TestMode
   #define TestMode
#endif
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   #ifdef TestMode
      Print("Test mode");
   #else
      Print("Normal mode");
   #endif
  }

В зависимости от типа программы и режима компиляции стандартные макросы определяются следующим образом:

Макрос __MQL5__  доступен при компиляции файла *.mq5, при компиляции *.mq4 доступен макрос __MQL4__.
Макрос _DEBUG доступен при компиляции под отладку.
Макрос _RELEASE доступен при компиляции не под отладку.

Пример:

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   #ifdef __MQL5__
      #ifdef _DEBUG
         Print("Hello from MQL5 compiler [DEBUG]");
      #else
        #ifdef _RELEASE
           Print("Hello from MQL5 compiler [RELEASE]");
        #endif
     #endif
   #else
      #ifdef __MQL4__
         #ifdef _DEBUG
           Print("Hello from MQL4 compiler [DEBUG]");
        #else
           #ifdef _RELEASE
              Print("Hello from MQL4 compiler [RELEASE]");
           #endif
        #endif
     #endif
   #endif
  }