Bug: Bitwise Operations broken in MT4 build 971

 

The following script compiles successfully, but hangs MetaTrader 4 (build 971) after run:

 

class Market {

public:

    static double GetPipDigits() {

        if (Digits < 4) {

            return 2;

        } else {

            return 4;

        }

    }


    static double GetLotstep() {

      double lot_step = fmax(MarketInfo(_Symbol, MODE_LOTSTEP), 10 >> GetPipDigits());

      return lot_step;

    }

};


int OnInit() {

   Alert(Market::GetLotstep());

   ExpertRemove();

}

 

When run from the terminal, it complains that the EX4 file is invalid (despite it was compiled fine):

EURUSD,M1: invalid EX4 file (8)

EURUSD,M1: global initialization failed

 

Tell it to the Service Desk: in you Profile on the left side Service Desk.

Or try this:

Save the file under a different name: File => Save as...

Now choose the original name and compile the file again and try to run it.

It seems to me that I have this problem if I try to run a file in the debugger: The debugger started but thing happens. Then I have to do that and the debugger works fine again.

I already told that to the Service Desk (Aug. 2015)


 
  1. You are trying to do a bit shift with a double. Either typecast it as an integer:
    double lot_step = fmax( MarketInfo(_Symbol, MODE_LOTSTEP), 10 >> int( GetPipDigits() ) );
    or just make the "GetPipDigits()" return an integer:
    static int GetPipDigits() { ... };
  2. Be careful when shifting. It is a binary shift and not a decimal shift, so 10 >> 2 = 2 and 10 >> 4 = 0 which seems like nonsense when comparing it to lot size.
  3. Lot Size Step and number of Digits of a Symbol have no relationship with each other. I hope your code is just a nonsense example, because in terms of logic it makes no sense to calculate "lot step" based on a function of "digits".
  4. You cannot use "ExpertRemove()" in a script (only in an EA). Just return "INIT_FAILED" from the "OnInit()" event handler instead (also valid for EAs).
  5. You are not returning any value from the "OnInit()" function, even though you correctly defined it as returning an "int" value (see point 4).
  6. Use the "#property strict" so as to have the compiler warn you of extra problems such as point 5.

PS! Fixing these points will no longer generate an invalid ".EX4". In fact, point 1 alone is enough to correct the "Invalid EX4" error, but the other points are just as important.

Here is a short hand version of the corrected code with some extra debuging "Prints":

#property strict

class Market
{
   public:
      static int GetPipDigits()
      { return( ( _Digits < 4 ) ? 2 : 4 ); }

      static double GetLotstep()
      { return( fmax( MarketInfo( _Symbol, MODE_LOTSTEP ), 10 >> GetPipDigits() ) ); }
};

int OnInit()
{
   Print( "10 >> 2 = ", 10 >> 2 );
   Print( "10 >> 4 = ", 10 >> 4 );
   Alert( Market::GetLotstep() );
   return( INIT_FAILED );
}
Reason: