MQL4 Reference Language Basics Preprocessor Macro substitution (#define)

Macro substitution (#define, #undef)

The #define directive can be used to assign mnemonic names to constants. There are two forms:

#define identifier expression                   // parameter-free form
#define identifier(par1,... par8) expression    // parametric form

The #define directive substitutes expression for all further found entries of identifier in the source text. The identifier is replaced only if it is a separate token. The identifier is not replaced if it is part of a comment, part of a string, or part of another longer identifier.

The constant identifier is governed by the same rules as variable names. The value can be of any type:

#define ABC               100
#define PI                3.14
#define COMPANY_NAME      "MetaQuotes Software Corp."
...
void ShowCopyright()
  {
   Print("Copyright  2000-2024, ",COMPANY_NAME);
   Print("https://www.metaquotes.net");
  }

expression can consist of several tokens, such as keywords, constants, constant and non-constant expressions. expression ends with the end of the line and can't be transferred to the next line.

Example:

#define TWO        2
#define THREE      3
#define INCOMPLETE TWO+THREE
#define COMPLETE  (TWO+THREE)
void OnStart()
  {
   Print("2 + 3*2 = ",INCOMPLETE*2);
   Print("(2 + 3)*2 = ",COMPLETE*2);
  }
// Result
// 2 + 3*2 = 8
// (2 + 3)*2 = 10

 

Parametric Form #define

With the parametric form, all the subsequent found entries of identifier will be replaced by expression taking into account the actual parameters. For example:

 // example with two parameters a and b
#define A 2+3
#define B 5-1
#define MUL(a, b) ((a)*(b))
 
double c=MUL(A,B);
Print("c=",c);
/*
expression double c=MUL(A,B);
is equivalent to double c=((2+3)*(5-1));
*/
// Result
// c=20

Be sure to enclose parameters in parentheses when using the parameters in expression, as this will help avoid non-obvious errors that are hard to find. If we rewrite the code without using the brackets, the result will be different:

 // example with two parameters a and b
#define A 2+3
#define B 5-1
#define MUL(a, b) a*b
 
double c=MUL(A,B);
Print("c=",c);
/*
expression double c=MUL(A,B);
is equivalent to double c=2+3*5-1;
*/
// Result
// c=16

When using the parametric form, maximum 8 parameters are allowed.

 // correct parametric form
#define LOG(text)  Print(__FILE__,"(",__LINE__,") :",text)   // one parameter - 'text'
 
 // incorrect parametric form         
#define WRONG_DEF(p1, p2, p3, p4, p5, p6, p7, p8, p9)   p1+p2+p3+p4 // more than 8 parameters from p1 to p9

The #undef directive

The #undef directive cancels declaration of the macro substitution, defined before.

Example:

#define MACRO
 
void func1()
  {
#ifdef MACRO
   Print("MACRO is defined in ",__FUNCTION__);   
#else
   Print("MACRO is not defined in ",__FUNCTION__);
#endif
  }
 
#undef MACRO
 
void func2()
  {
#ifdef MACRO
   Print("MACRO is defined in ",__FUNCTION__);
#else
   Print("MACRO is not defined in ",__FUNCTION__);
#endif
  }
 
void OnStart()
  {
   func1();
   func2();
  }
 
/* Result:
 MACRO is defined in func1
 MACRO is not defined in func2
*/

See also

Identifiers, Character Constants