Search code examples
compiler-errorssyntax-errorconditional-statementspreprocessor-directivemql4

How to use a logical operator for a preprocessor conditional in an #ifdef compilation directive?


I've the following code which is using preprocessor conditional compilation directives:

#define foo
#define bar

#ifdef foo || !bar
  extern bool Verbose = FALSE;
#else
  extern bool Verbose = TRUE;
#endif

void start() {
}

which doesn't compile, because of the following error:

test.mq4(3,12) : error 175: '||' - expressions are not allowed on a global scope

However the code compiles fine when the first line (foo) is commented out which seems the compiler allows this expression in a global scope in that case (when foo is not defined).

You can try compiling above code using mql compilator (under Linux use wine):

mql.exe /mql4 test.mq4

So the question is:

Why this doesn't work
and
how do I define above preprocessor condition (foo || !bar)
in a proper way?


I've also tried the following syntax:

#if defined (foo) || defined (!bar)

as suggested previously by user2357112 (GNU cpp syntax), but it fails with the following errors:

error 109: '#if' - invalid preprocessor command

error 149: '#else' - unexpected token

it's because the MQL syntax is completely different and it doesn't support these kind preprocessor commands.


Solution

  • Why this does not work?

    Because
    the condition syntax does not meet the specifications of MQL4preprocessor.
    ( rather once more 've checked and cross-checked the MQL4 Documentation
    Section:
    [
    MQL4 Reference / Language Basics / Preprocessor / Conditional Compilation (#ifdef, #ifndef, #else, #endif) ] )


    Preprocessor conditional compilation directives allow compiling or skipping a part of the program depending on the fulfillment of a certain condition.

    That condition can take one of the following forms.

    #ifdef identifier
    // ... the code located here is compiled
    // ... if identifier has already been defined for the preprocessor in #define directive.
    #endif

    #ifndef identifier
    // ... the code located here is compiled
    // ... if identifier is not currently defined by preprocessor #define directive.
    #endif

    A condition is, in this MQL4 preprocessor context, a member of a static, closed set of recognised syntactic directive-constructors { #ifdef | #ifndef | #else }

    An identifier is, in this MQL4 preprocessor context, a constant term, not an expression.

    Q.E.D.


    A proper way?

    One still might opt to construct the missing logic-flexibility "manually":

    #ifdef bar_identifier
        #ifndef foo_indentifier
             extern bool aCompileTimePresetDefaultToExposedEXTERN_USER_INPUT = True;
        #else
             extern bool aCompileTimePresetDefaultToExposedEXTERN_USER_INPUT = False;
        #endif
    #else
             extern bool aCompileTimePresetDefaultToExposedEXTERN_USER_INPUT = False;
    #endif