Sostituzioni Macro predefinite

Per semplificare il processo di debug e ottenere informazioni sul funzionamento di un programma-MQL5, ci sono macro costanti speciali, i cui valori sono stabiliti al momento della compilazione. Il modo più semplice per utilizzare queste costanti è l'output di valori dalla funzione Print(), come è illustrato nell'esempio.

Constant

Descrizione

__CPU_ARCHITECTURE__

Nome dell'architettura (set di comandi) per il quale il file EX5 viene compilato

__DATE__

Compilazione di file senza orario (ore, minuti e secondi sono uguali a 0)

__DATETIME__

Data ed ora di compilazione del file

__LINE__

Numero di riga nel codice sorgente, in cui si trova la macro

__FILE__

Nome del file attualmente elaborati

__PATH__

Un percorso assoluto del file che è attualmente in fase di compilazione

__FUNCTION__

Nome della funzione, nel cui corpo si trova la macro

__FUNCSIG__

Firma della funzione nel cui corpo si trova la macro. Logging della descrizione completa delle funzioni può essere utile per l'identificazione di funzioni sovraccaricate

__MQLBUILD__, __MQL5BUILD__

Numero di build compilatore

__COUNTER__

The compiler for each encountered __COUNTER__ declaration substitutes the counter value from 0 to N-1 where N is a number of uses in the code.  The __COUNTER__ order is guaranteed when recompiling the source code with no changes.

The __COUNTER__ value is calculated the following way:

  • the initial counter value is 0,
  • after each counter usage, its value is increased by 1,
  • first, the compiler expands all macros and templates into source code on-site,
  • a separate code is created for each template function specialization,
  • a separate code is created for each template class/structure specialization,
  • next, the compiler passes through the obtained source code in the defined order and replaces each detected __COUNTER__ usage with the current counter value.

The example below shows how the compiler handles the source code and replaces all instances of __COUNTER__ it meets with sequentially increasing values.

__RANDOM__

The compiler inserts a random ulong value for each __RANDOM__ declaration.

Esempio:

#property copyright "Copyright © 2009, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net"
//+--------------------------------------------------------------------------------+
//| Funzione di inizializzazione dell' Expert                                      |
//+--------------------------------------------------------------------------------+
void OnInit()
  {
//--- un esempio di output dati in fase di inizializzazione Expert Advisor
   Print(" __FUNCTION__ = ",__FUNCTION__,"  __LINE__ = ",__LINE__);
//--- impostare l'intervallo tra gli eventi timer
   EventSetTimer(5);
//---
  }
//+--------------------------------------------------------------------------------+
//| Funzione deinizializzazione Expert                                             |
//+--------------------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- un esempio di informazioni output alla deinizializzazione Expert Advisor
   Print(" __FUNCTION__ = ",__FUNCTION__,"  __LINE__ = ",__LINE__);
//---
  }
//+--------------------------------------------------------------------------------+
//| Funzione tick dell'Expert                                                      |
//+--------------------------------------------------------------------------------+
void OnTick()
  {
//--- output informazioni al ricevimento tick
   Print(" __FUNCTION__ = ",__FUNCTION__,"  __LINE__ = ",__LINE__);
   Print(" __FUNCTION__ = ",__FUNCTION__,"  __LINE__ = ",__LINE__);
   test1(__FUNCTION__);
   test2();
//---
  }
//+--------------------------------------------------------------------------------+
//| test1                                                                          |
//+--------------------------------------------------------------------------------+
void test1(string par)
  {
//--- output informazioni all'interno della funzione
   Print(" __FUNCTION__ = ",__FUNCTION__,"  __LINE__ = ",__LINE__," par=",par);
  }
//+--------------------------------------------------------------------------------+
//| test2                                                                          |
//+--------------------------------------------------------------------------------+
void test2()
  {
//--- output informazioni all'interno della funzione
   Print(" __FUNCTION__ = ",__FUNCTION__,"  __LINE__ = ",__LINE__);
  }
//+--------------------------------------------------------------------------------+
//| OnTimer event handler                                                          |
//+--------------------------------------------------------------------------------+
void OnTimer()
  {
//---
   Print(" __FUNCTION__ = ",__FUNCTION__,"  __LINE__ = ",__LINE__);
   test1(__FUNCTION__);
  }

 

The example for learning how to work with the __COUNTER__ macro

//--- create a macro for a quick display of the expression and its value in the journal
#define print(exprPrint(#expr,"=",expr)
 
//--- define the MACRO_COUNTER custom macro via the predefined __COUNTER__ macro
#define MACRO_COUNTER __COUNTER__
 
//--- set the input value of the variable using the __COUNTER__ macro
input int InpVariable = __COUNTER__;
 
//--- set the value of the global variable using the __COUNTER__ macro before defining the functions
int ExtVariable = __COUNTER__;
 
//+------------------------------------------------------------------+
//| the function returns the __COUNTER__ value                       |
//+------------------------------------------------------------------+
int GlobalFunc(void)
  {
   return(__COUNTER__);
  }
//+------------------------------------------------------------------+
//| the template function returns the __COUNTER__ value              |
//+------------------------------------------------------------------+
template<typename T>
int GlobalTemplateFunc(void)
  {
   return(__COUNTER__);
  }
//+------------------------------------------------------------------+
//| the structure with the method returning __COUNTER__              |
//+------------------------------------------------------------------+
struct A
  {
   int               dummy;  // not used
 
   int               Method(void)
     {
      return(__COUNTER__);
     }
  };
//+------------------------------------------------------------------+
//| the template structure with the method returning __COUNTER__     |
//+------------------------------------------------------------------+
template<typename T>
struct B
  {
   int               dummy;  // not used
 
   int               Method(void)
     {
      return(__COUNTER__);
     }
  };
//+------------------------------------------------------------------+
//| the structure with the template method returning __COUNTER__     |
//+------------------------------------------------------------------+
struct C
  {
   int               dummy;  // not used
 
   template<typename T>
   int               Method(void)
     {
      return(__COUNTER__);
     }
  };
//+------------------------------------------------------------------+
//| the function #2, which returns the __COUNTER__ value             |
//+------------------------------------------------------------------+
int GlobalFunc2(void)
  {
   return(__COUNTER__);
  }
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart(void)
  {
// __COUNTER__ in the macro and the variables
   print(MACRO_COUNTER);
   print(InpVariable);
   print(ExtVariable);
 
//--- __COUNTER__ in the functions
   print(GlobalFunc());
   print(GlobalFunc());                // the value is not changed
   print(GlobalTemplateFunc<int>());
   print(GlobalTemplateFunc<int>());   // the value is not changed
   print(GlobalTemplateFunc<double>());// the value has changed
   print(GlobalFunc2());
   print(GlobalFunc2());               // the value is not changed
 
// __COUNTER__ in the structure
   A a1a2;
   print(a1.Method());
   print(a2.Method());                 // the value is not changed
 
// __COUNTER__ in the template structure
   B<intb1b2;
   B<doubleb3;
   print(b1.Method());
   print(b2.Method());                 // the value is not changed
   print(b3.Method());                 // the value has changed
 
// __COUNTER__ in the structure with the template function
   C c1c2;
   print(c1.Method<int>());
   print(c1.Method<double>());         // the value has changed
   print(c2.Method<int>());            // the same value as during the first c1.Method<int>() call
 
//--- let's have another look at __COUNTER__ in the macro and the global variable
   print(MACRO_COUNTER);  // the value has changed
   print(ExtGlobal2);
  }
//--- set the value of the global variable using the __COUNTER__ macro after defining the functions
int ExtGlobal2 = __COUNTER__;
//+------------------------------------------------------------------+
 
/* Result
   __COUNTER__=3
   InpVariable=0
   ExtVariable=1
   GlobalFunc()=5
   GlobalFunc()=5
   GlobalTemplateFunc<int>()=8
   GlobalTemplateFunc<int>()=8
   GlobalTemplateFunc<double>()=9
   GlobalFunc2()=7
   GlobalFunc2()=7
   a1.Method()=6
   a2.Method()=6
   b1.Method()=10
   b2.Method()=10
   b3.Method()=11
   c1.Method<int>()=12
   c1.Method<double>()=13
   c2.Method<int>()=12
   __COUNTER__=4
   ExtGlobal2=2
 
*/