Substituições de Macro Predefinidas

Para simplificar o processo de depuração e obter informações sobre a operação de um programa-mql5, existem constantes de macro especiais, valores que são definidos no momento da compilação. A forma mais fácil de usar estas constantes é imprimir estes valores através da função Print(), como é mostrado no exemplo.

Constante

Descrição

__CPU_ARCHITECTURE__        

Nome da arquitetura (conjunto de comandos) para a qual o arquivo EX5 é criado no momento da compilação

__DATE__

Data de compilação do arquivo sem a hora (horas, minutos e segundos são iguais a 0)

__DATETIME__

Data e hora de compilação do arquivo

__LINE__

Assinatura da função em cujo corpo a macro está localizada.

__FILE__

Nome do arquivo compilado corrente

__PATH__

O caminho absoluto para o arquivo que está sendo compilado correntemente

__FUNCTION__

Nome da função, em cujo corpo a macro está localizada

__FUNCSIG__

Assinatura da função em cujo corpo a macro está localizada. O registro da descrição completa de funções pode ser útil na identificação de funções sobrecarregadas

__MQLBUILD__, __MQL5BUILD__

Número do compilação

__COUNTER__

Para cada declaração de __COUNTER__ que encontra, o compilador substitui no local o valor do contador de 0 a N-1, onde N é o número de usos no código. Ao recompilar o código-fonte sem alterações, a ordem de __COUNTER__ é garantida.

O valor do contador __COUNTER__ é calculado da seguinte forma:

  • o valor inicial do contador é 0,
  • após cada uso do contador, seu valor é aumentado em 1,
  • primeiro, o compilador expande todas as macros e modelos em código-fonte no local,
  • código separado é gerado para cada especialização da função baseada em modelo,
  • código separado é gerado para cada especialização da classe/estrutura baseada em modelo,
  • o compilador então percorre o código-fonte resultante usando a ordem definida e substitui cada uso de __COUNTER__ que encontra pelo valor do contador atual.

No exemplo abaixo, você pode ver claramente como o compilador processa o código-fonte e substitui o __COUNTER__ encontrado com valores crescentes sequencialmente.

__RANDOM__

Para cada declaração de __RANDOM__, o compilador substitui um número aleatório ulong no código.

Exemplo:

#property copyright "Copyright © 2009, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net"
//+------------------------------------------------------------------+
//| Função de inicialização do Expert                                |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- um exemplo de impressão de informação na inicialização de um Expert Advisor
   Print(" __FUNCTION__ = ",__FUNCTION__,"  __LINE__ = ",__LINE__);
//--- define o intervalo entre os eventos timer
   EventSetTimer(5);
//---
  }
//+------------------------------------------------------------------+
//| Função de Desinicialização do Expert                             |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- um exemplo de impressão de informação na desinicialização de um Expert Advisor
   Print(" __FUNCTION__ = ",__FUNCTION__,"  __LINE__ = ",__LINE__);
//---
  }
//+------------------------------------------------------------------+
//| Função tick (ponto) de um Expert                                 |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- impressão de informação no recebimento de um tick
   Print(" __MQLBUILD__ = ",__MQLBUILD__,"  __FILE__ = ",__FILE__);
   Print(" __FUNCTION__ = ",__FUNCTION__,"  __LINE__ = ",__LINE__);
   test1(__FUNCTION__);
   test2();
//---
  }
//+------------------------------------------------------------------+
//| test1                                                            |
//+------------------------------------------------------------------+
void test1(string par)
  {
//--- impressão de informação dentro da função
   Print(" __FUNCTION__ = ",__FUNCTION__,"  __LINE__ = ",__LINE__," par=",par);
  }
//+------------------------------------------------------------------+
//| test2                                                            |
//+------------------------------------------------------------------+
void test2()
  {
//--- impressão de informação dentro da função
   Print(" __FUNCTION__ = ",__FUNCTION__,"  __LINE__ = ",__LINE__);
  }
//+------------------------------------------------------------------+
//| OnTimer event handler                                            |
//+------------------------------------------------------------------+
void OnTimer()
  {
//---
   Print(" __FUNCTION__ = ",__FUNCTION__,"  __LINE__ = ",__LINE__);
   test1(__FUNCTION__);
  }

 

Exemplo para aprender a trabalhar com uma macro __COUNTER__

//--- criamos uma macro para impressão rápida da expressão e seu valor no log
#define print(exprPrint(#expr,"=",expr)
 
//--- definimos uma macro customizada MACRO_COUNTER por meio da macro predefinida __COUNTER__
#define MACRO_COUNTER __COUNTER__
 
//--- definimos o valor da variável input com a macro __COUNTER__
input int InpVariable = __COUNTER__;
 
//--- definimos o valor da variável global com a macro __COUNTER__ antes de definir as funções
int ExtVariable = __COUNTER__;
 
//+------------------------------------------------------------------+
//| a função retorna o valor __COUNTER__                             |
//+------------------------------------------------------------------+
int GlobalFunc(void)
  {
   return(__COUNTER__);
  }
//+------------------------------------------------------------------+
//| função de modelo retorna valor __COUNTER__                       |
//+------------------------------------------------------------------+
template<typename T>
int GlobalTemplateFunc(void)
  {
   return(__COUNTER__);
  }
//+------------------------------------------------------------------+
//| estrutura com um método que retorna __COUNTER__                  |
//+------------------------------------------------------------------+
struct A
  {
   int               dummy;  // não é usado
 
   int               Method(void)
     {
      return(__COUNTER__);
     }
  };
//+------------------------------------------------------------------+
//| estrutura baseada em modelo com um método que retorna __COUNTER__|
//+------------------------------------------------------------------+
template<typename T>
struct B
  {
   int               dummy;  // não é usado
 
   int               Method(void)
     {
      return(__COUNTER__);
     }
  };
//+------------------------------------------------------------------+
//| estrutura com um método baseado em modelo que retorna __COUNTER__|
//+------------------------------------------------------------------+
struct C
  {
   int               dummy;  // não é usado
 
   template<typename T>
   int               Method(void)
     {
      return(__COUNTER__);
     }
  };
//+------------------------------------------------------------------+
//| função #2, que retorna o valor __COUNTER__                       |
//+------------------------------------------------------------------+
int GlobalFunc2(void)
  {
   return(__COUNTER__);
  }
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart(void)
  {
// __COUNTER__ em macros e variáveis
   print(MACRO_COUNTER);
   print(InpVariable);
   print(ExtVariable);
 
/--- __COUNTER__ em funções
   print(GlobalFunc());
   print(GlobalFunc());                // o valor não muda
   print(GlobalTemplateFunc<int>());
   print(GlobalTemplateFunc<int>());   // o valor não muda
   print(GlobalTemplateFunc<double>());// o valor mudou
   print(GlobalFunc2());
   print(GlobalFunc2());               // o valor não muda
 
// __COUNTER__ na estrutura
   A a1a2;
   print(a1.Method());
   print(a2.Method());                 // o valor não muda
 
// __COUNTER__ na estrutura baseada em modelo
   B<intb1b2;
   B<doubleb3;
   print(b1.Method());
   print(b2.Method());                 // o valor não muda
   print(b3.Method());                 // o valor mudou
 
// __COUNTER__ em uma estrutura com uma função baseada em modelo
   C c1c2;
   print(c1.Method<int>());
   print(c1.Method<double>());         // o valor mudou
   print(c2.Method<int>());            // valor como ao chamar c1.Method<int>() pela primeira vez
 
//--- mais uma vez, olhamos para __COUNTER__ na macro e na variável global
   print(MACRO_COUNTER);  // o valor mudou
   print(ExtGlobal2);
  }
//--- definimos o valor da variável global com a macro __COUNTER__ após as definições da função
int ExtGlobal2 = __COUNTER__;
//+------------------------------------------------------------------+
 
/* Resultado
   __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
 
*/