0

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.

Community
  • 1
  • 1
kenorb
  • 155,785
  • 88
  • 678
  • 743
  • What were you trying to do with `#ifdef foo || !bar`? It's not like `foo || !bar` can have a preprocessing definition associated with it. Were you trying to test "foo is defined or bar isn't defined"? – user2357112 Oct 09 '15 at 22:42
  • @user2357112 Yes, to avoid repeated unnecessary nested conditions for 4 different possibilities. When the condition is not covered, the compiler complain that it's not defined, if it's defined before, it complains that it's already defined. – kenorb Oct 09 '15 at 22:43
  • @kenorb it might be worth stating, "***new***"-`MQL4` compiler is `MetaLang.exe` ( which might have troubles with automated LiveUpdate revisions inside **`WINE`** wrapper ) and as such has nothing to do with any part of the **`gcc`** toolchain. So, included documentation rulez. Welcome to the world of `MQL4` moving sands. ( check other posts about this painfull life, if interested to spend a few man*decades in hacking with continuously "*sliding*" `MetaLang.exe` "*new*-**`MQL4`**" syntax rules `:o)` ) – user3666197 Oct 10 '15 at 16:50
  • @user3666197 I thought `metalang.exe` (prior to build 600) was the old compiler and it's no longer shipped with platform it-self (as I've explained it [here](http://stackoverflow.com/a/32459182/55075)), so I'm using `mql.exe` and it works perfectly fine under `wine`. If you think it's not the new one, where you can get the latest? I think it's latest, because it says: `02 Jul 2015`. I know it's similar and nothing to do with `gcc`, but previous answer (deleted now) was attempting to answer in terms of it, so I did some additional clarification to avoid any further attempts or confusion. – kenorb Oct 10 '15 at 18:21
  • @user3666197 I'm also a bit disappointed with the syntax, too much limitations there. You can't actually write any flexible code in it. – kenorb Oct 10 '15 at 18:25
  • @kenorb Btw, quite interested, what version does your **`WINE`**-ecosystem operate? `2 Jul 2015` sounds like older than actual `MetaEditor.exe; Build 1174; 2015-09-25`. How do you update it? In recent post-new-MQL4 era, whenever you use `[F1]` help, the editor used to inform you ( might got suppresed recently ) about loading a new help file, **which directly warned you**, there is something changed in the syntax. **How do you survive this creeping in `WINE`?** Btw, it is much bigger fun to operate `MQL4` side as a client of a distributed system, where one can enjoy limitless code-execution – user3666197 Oct 10 '15 at 22:12
  • 1
    @user3666197 This was the version of the compiler it-self, so I think they're versioned differently and it supports the latest syntax (btw. never used [F1], usually checking on-line docs). The compiler and terminal works under wine-1.6&1.7. Btw. I actually managed to do fully [virtualized backtests](https://github.com/EA31337/FX-MT-VM) under wine, so you can test the terminal in ready-to-use Vagrant VM. – kenorb Oct 10 '15 at 22:30

1 Answers1

3

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
user3666197
  • 1
  • 6
  • 50
  • 92