"array out of range" only when using "#property strict"

 

Hi

This is a simple fractal indicator. 

MAIN QUESTION : Why getting  "array out of range" error only when using "#property strict" ?


//+------------------------------------------------------------------+
//|                                                     Fractals.mq4 |
//|                      Copyright © 2005, MetaQuotes Software Corp. |
//|                                                 Update by Kharko |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
#property strict   // THIS CODE WORKS WHITHOUT strict   ONLY
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Blue
#property indicator_width1 1
#property indicator_width2 1
//---- input parameters
//---- buffers
double ExtUpFractalsBuffer[];
double ExtDownFractalsBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+

int OnInit()
   {
//---- indicator buffers mapping  
    SetIndexBuffer(0,ExtUpFractalsBuffer);
    SetIndexBuffer(1,ExtDownFractalsBuffer);   
//---- drawing settings
    SetIndexStyle(0,DRAW_ARROW);
    SetIndexArrow(0,119);
    SetIndexStyle(1,DRAW_ARROW);
    SetIndexArrow(1,119);
//----
    SetIndexEmptyValue(0,0.0);
    SetIndexEmptyValue(1,0.0);
//---- name for DataWindow
    SetIndexLabel(0,"Fractal Up");
    SetIndexLabel(1,"Fractal Down");
//---- initialization done   
   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Comment("");
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total, // total bars
                const int prev_calculated, // calculated bars by indicator
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {

int limit = rates_total+3;
int count=prev_calculated;
int    i;
bool   bFound;
double dCurrent;
   for( i=limit-count+3; i>=1;i--)  
     {
      //------------------------Fractals up - START
         dCurrent =   High[i];
         bFound=false;
         
         if                                  (dCurrent>High[i+1] && dCurrent>High[i+2] && dCurrent>High[i-1] && dCurrent>High[i-2] && Volume[i-3]>0) bFound=true; //----5 bars Fractal
         if (  (!bFound && (Bars-i-1)>=3) && (dCurrent==High[i+1] && dCurrent>High[i+2] && dCurrent>High[i+3] && dCurrent>High[i-1] && dCurrent>High[i-2] && Volume[i-3]>0)  ) bFound=true;    //----6 bars Fractal
         if (  (!bFound && (Bars-i-1)>=4) && (dCurrent>=High[i+1] && dCurrent==High[i+2] && dCurrent>High[i+3] && dCurrent>High[i+4] && dCurrent>High[i-1] && dCurrent>High[i-2] && Volume[i-3]>0) ) bFound=true;   //----7 bars Fractal
         if (  (!bFound && (Bars-i-1)>=5) && (dCurrent>=High[i+1] && dCurrent==High[i+2] && dCurrent==High[i+3] && dCurrent>High[i+4] && dCurrent>High[i+5] && dCurrent>High[i-1] && dCurrent>High[i-2] && Volume[i-3]>0)  ) bFound=true;   //----8 bars Fractal 
         if (  (!bFound && (Bars-i-1)>=6) && (dCurrent>=High[i+1] && dCurrent==High[i+2] && dCurrent>=High[i+3] && dCurrent==High[i+4] && dCurrent>High[i+5] && dCurrent>High[i+6] && dCurrent>High[i-1] && dCurrent>High[i-2] && Volume[i-3]>0)   ) bFound=true;   //----9 bars Fractal  

         if (bFound)
         {
            ExtUpFractalsBuffer[i]=dCurrent;
         }
      //------------------------Fractals down
          dCurrent=Low[i];
         bFound=false;
         if                                  (dCurrent<Low[i+1] && dCurrent<Low[i+2] && dCurrent<Low[i-1] && dCurrent<Low[i-2] && Volume[i-3]>0)  bFound=true; //----5 bars Fractal
         if (  (!bFound && (Bars-i-1)>=3) && (dCurrent==Low[i+1] && dCurrent<Low[i+2] && dCurrent<Low[i+3] && dCurrent<Low[i-1] && dCurrent<Low[i-2] && Volume[i-3]>0)  ) bFound=true;  //----6 bars Fractal
         if (  (!bFound && (Bars-i-1)>=4) && (dCurrent<=Low[i+1] && dCurrent==Low[i+2] && dCurrent<Low[i+3] && dCurrent<Low[i+4] && dCurrent<Low[i-1] && dCurrent<Low[i-2] && Volume[i-3]>0) ) bFound=true;  //----7 bars Fractal
         if (  (!bFound && (Bars-i-1)>=5) && (dCurrent<=Low[i+1] && dCurrent==Low[i+2] && dCurrent==Low[i+3] && dCurrent<Low[i+4] && dCurrent<Low[i+5] && dCurrent<Low[i-1] && dCurrent<Low[i-2] && Volume[i-3]>0)   )  bFound=true; //----8 bars Fractal
         if (  (!bFound && (Bars-i-1)>=6) && (dCurrent<=Low[i+1] && dCurrent==Low[i+2] && dCurrent<=Low[i+3] && dCurrent==Low[i+4] && dCurrent<Low[i+5] && dCurrent<Low[i+6] && dCurrent<Low[i-1] && dCurrent<Low[i-2] && Volume[i-3]>0)  )   bFound=true; //----9 bars Fractal

         if (bFound)
         {   
            ExtDownFractalsBuffer[i]=dCurrent;
         }
  
     }
//----
   return(0);
  }
//+------------------------------------------------------------------+
 
KSforex:

MAIN QUESTION : Why getting  "array out of range" error only when using "#property strict" ?

What the +3 mean? I have tried to understand it.

"while(i>=3)" means that we always need 3 bars in front? and fractals drawing for bar number 3  or more? 

"i=Bars-nCountedBars+3" means that we want tell to indicator that always there is 3 un-checked bars , because it stop working if "i" equal to 0 ir i<3 ?

  1. With strict, bad references (negative or beyond maximum) results in an error. Without, the error is hidden and all you get is a zero.

  2. It means three.Three

  3. if(dCurrent<Low[i+1] && dCurrent<Low[i+2] && dCurrent<Low[i-1] && dCurrent<Low[i-2] && Volume[i-3]>0)
    The i-3 means you are looking 3 bars in the future (relative to i) If there aren't three bars there's nothing to access. By the way, you will never, ever, see a zero volume, (no tick, no bar.)

  4. i=Bars-nCountedBars+3;  
    Bogus. It is trying to make sure there are 3 bars in the past. See How to do your lookbacks correctly.

  5. Why did you post your MT4 question in the Root / MT5 Indicators section instead of the MQL4 section, (bottom of the Root page?)
              General rules and best pratices of the Forum. - General - MQL5 programming forum
    Next time post in the correct place. The moderators will likely move this thread there soon.

  6. Start using the new Event Handling Functions.
              Event Handling Functions - Functions - Language Basics- MQL4 Reference

 
whroeder1:
  1. With strict, bad references (negative or beyond maximum) results in an error. Without, the error is hidden and all you get is a zero.


I dont understand your mean please answer MAIN QUESTION:

Why getting "array out of range" error only when using "#property strict" on this code?




whroeder1:

6. Start using the new Event Handling Functions. 

     Event Handling Functions - Functions - Language Basics- MQL4 Reference

     

Ok done. now check new code (first post edited) and tell me why still getting "out of range error" when using "#property strict" while it works fine without strict.

 
KSforex:


I dont understand your mean please answer MAIN QUESTION:

Why getting "array out of range" error only when using "#property strict" on this code?




     

Ok done. now check new code (first post edited) and tell me why still getting "out of range error" when using "#property strict" while it works fine without strict.

First you must understand why there is the strict directive in the first place. The early builds of MQL4 allowed some really dangerous errors to fly because code needed to be somewhat compatible with MQL3. With the "new" version of MQL4, MQ introduced more modern and "strict" code linting which checks the context so that metaeditor won't compile your source to bytecode if there are obvious errors. Along with strict linting it also will terminate a program not behaving correctly. This is important because when you don't use "strict" linting (compiling) then array out of range and other errors are allowed to pass silently which could result in some catastrophic side effects when real money is on the line. TL;DR You still have array out of range, but removing strict just allows it to pass silently (dangerously). 
 
nicholi shen:
First you must understand why there is the strict directive in the first place. The early builds of MQL4 allowed some really dangerous errors to fly because code needed to be somewhat compatible with MQL3. With the "new" version of MQL4, MQ introduced more modern and "strict" code linting which checks the context so that metaeditor won't compile your source to bytecode if there are obvious errors. Along with strict linting it also will terminate a program not behaving correctly. This is important because when you don't use "strict" linting (compiling) then array out of range and other errors are allowed to pass silently which could result in some catastrophic side effects when real money is on the line. TL;DR You still have array out of range, but removing strict just allows it to pass silently (dangerously). 

Thanks for help!


The problem solved by this code :

This code "if ((Bars-i)>=7)" mean it should not do anything for first 7 bars or more. because  we need enough bars to calculate fractals. It should be the reason for strict mode failure . right?

   for( i=limit-count; i>=3;i--)  

     {

     if ((Bars-i)>=7)

     {



But the code was compiled without error. if the code has an error it should not be compiled . This bug need to be fixed in meta editor and errors should be shown .

 
KSforex:

But the code was compiled without error. if the code has an error it should not be compiled . This bug need to be fixed in meta editor and errors should be shown .

The compiler does a good job on picking up and warning about some sloppy coding.

Do you really expect it to check errors in execution while compiling?

 
KSforex: I dont understand your mean please answer MAIN QUESTION: Why getting "array out of range" error only when using "#property strict" on this code?

Asked and answered. What part of "With strict, bad references (negative or beyond maximum) results in an error. Without, the error is hidden and all you get is a zero." don't you understand?

 
So, I understand that those hundreds or thousands of indicators written without #property strict are bad, dangerous? We can't do like in the attached images??? BTW, very many of them written by the MQL4 staff!!!
 
Dadas #: So, I understand that those hundreds or thousands of indicators written without #property strict are bad, dangerous?

Neither. If they do not access nonexistent elements, the result is the same with and without strict. Strict is trying to help you.

Always use strict. Fixing the warnings will save you hours of debugging, but you must understand the differences.

 
William Roeder #:

Neither. If they do not access nonexistent elements, the result is the same with and without strict. Strict is trying to help you.

Always use strict. Fixing the warnings will save you hours of debugging, but you must understand the differences.

So, you are saying that all of those codes should be rewritten to the strict mode?
Always use strict - and they don't use strict.
If the strict property is defined, they return array out of range.

I know your post where you show the new method of counting, and that works, but that requires to modify the code.

 
Dadas #: So, you are saying that all of those codes should be rewritten to the strict mode? Always use strict - and they don't use strict. If the strict property is defined, they return array out of range. I know your post where you show the new method of counting, and that works, but that requires to modify the code.

At the time those "old" codes were written there was no "strict" mode. It only came out later when the MQL4+ language update came out to make it more compatible to MQL5.

So, as long as the proper checks where done in the old MQL4 code, there is no need to have them rewritten.

It is going forward with the MQL4+ language available that one should always use "strict" mode, so as to help programmers write better more modern code.

Reason: