Features of the mql5 language, subtleties and tricks - page 152

 
Slava:

Is there one? Are you sure it's there? Which path is it on?

How can I reproduce it?

Place the script in the Navigator favourites.

void OnStart() {}


Compile the wrong version.

void OnStart() {} 123


Restart the Terminal and try editing the script from Favorites.

 
Vladimir Simakov:

Developers. An explanation is needed. Which to believe? The docs or the implementation? So far undefined behavior appears.

@fxsaber, I do not recommend you to use it before the official explanations, maybe they will fix it.

Documentation is backlogged, let's fix it.

I do not recommend initializing static variables with expressions, if possible use a constant.

Because when you use a non-constant expression, the compiler generates the following code

//--- исходная функция
int func(int value)
  {
   static int myStaticVar=value;    
   
   myStaticVar += value;
   return(myStaticVar);
  }

//--- то, что будет сгенерировано 
bool __Implicit_myStaticVar_initialized=false;
int  __Implicit_myStaticVar=0;

//--- исходная функция
int func(int value)
  {
   if(!__Implicit_myStaticVar_initialized)
     {
      __Implicit_myStaticVar_initialized=true;
      __Implicit_myStaticVar=value;
     }

   __Implicit_myStaticVar += value;
   return(__Implicit_myStaticVar);
  }


There is an overhead, each call will check the __Implicit_myStaticVar_initialized flag

For the constant case, you will get the following code

//--- исходная функция
int func(int value)
  {
   static int myStaticVar=10;

   myStaticVar += value;
   return(myStaticVar);
  }

//--- то, что будет сгенерировано 
int  __Implicit_myStaticVar=10;

int func(int value)
  {
   __Implicit_myStaticVar += value;
   return(__Implicit_myStaticVar);
  }

There is no overhead.

 
Ilyas:

Thank you, now I understand about the overhead.

 
You can easily write non-normalised price values to custom characters. Below is a simple check.
bool IsNorm( const double Price )
{
  return(NormalizeDouble(Price, _Digits) == Price);
}

#define  TOSTRING(A) #A + " = " + DoubleToString(A, 16) + " "
#define  PRINT(A) Print(TOSTRING(A) + TOSTRING(NormalizeDouble(A, _Digits)))
#define  ISNORM(A) if (!IsNorm(A)) PRINT(A);

void OnTick()
{
  MqlTick Tick;
  
  if (SymbolInfoTick(_Symbol, Tick))
  {
    ISNORM(Tick.bid)
    ISNORM(Tick.ask)
    ISNORM(Tick.last)
  }
}


Result

2019.12.11 06:46:56.458 2019.10.09 23:59:00   Tick.last = 1.8151900000000002 NormalizeDouble(Tick.last,_Digits) = 1.8151900000000000 
2019.12.11 06:46:56.458 2019.10.09 23:59:11   Tick.bid = 1.8151100000000003 NormalizeDouble(Tick.bid,_Digits) = 1.8151100000000001 
2019.12.11 06:46:56.458 2019.10.09 23:59:11   Tick.ask = 1.8153800000000003 NormalizeDouble(Tick.ask,_Digits) = 1.8153800000000001 
2019.12.11 06:46:56.458 2019.10.09 23:59:17   Tick.bid = 1.8151200000000002 NormalizeDouble(Tick.bid,_Digits) = 1.8151199999999999 
2019.12.11 06:46:56.458 2019.10.09 23:59:17   Tick.ask = 1.8153800000000003 NormalizeDouble(Tick.ask,_Digits) = 1.8153800000000001 
 
Comments not related to this topic have been moved to "Questions from MQL5 MT5 MetaTrader 5 beginners".
 
RickD:
... The question is different. Perhaps there is a bug in MQL5, we need to deal with it, but postponing it to the topic for newbies doesn't help us figure it out soon enough.

Please read the title of the topic.

 
Artyom Trishkin:

Please read the title of the thread.

And where do you see the contradiction? The situation described may be a feature of the language, or a bug. That is what you wanted to find out.

 
RickD:

And where do you see the contradiction? The situation described could be a feature of the language, or it could be a bug. That is what you wanted to find out.

No. First it is found out whether it is a bug or a peculiarity - then it is posted exactly, and exclusively a peculiarity. The topic is only about features.

 

@Ilyas@Slava@Renat Fatkhullin

mql has support for undocumented keywords for functions

__inline
__forceinline

Is it reasonable to use them?
If yes, when will the compiler accept them?

 

In the ArrayReverse help:

TheArraySetAsSeries()function does not physically move the elements of the array, but only reverses the indexing direction backwards to arrange access to the elements as in atimeseries. The ArrayReverse() function physically moves array items so that the array is "reversed".

But this code proves the opposite:

  MqlRates rt[];
  CopyRates(Symbol(), 0, 0, 5, rt);
  ArraySetAsSeries(rt, true);
  ArrayResize(rt, 6); // добавляет элемент в конец массива
  //ArraySetAsSeries(rt, true);
  for (int x = 0; x < ArraySize(rt); x++) {
      Print(rt[x].time);
  }
  Print("=================");
(EURUSD,H1)     2019.12.13 02:00:00
(EURUSD,H1)     2019.12.13 01:00:00
(EURUSD,H1)     2019.12.13 00:00:00
(EURUSD,H1)     2019.12.12 23:00:00
(EURUSD,H1)     2019.12.12 22:00:00
(EURUSD,H1)     1970.01.01 00:00:00 - последний элемент
(EURUSD,H1)     =================
  MqlRates rt[];
  CopyRates(Symbol(), 0, 0, 5, rt);
  //ArraySetAsSeries(rt, true);
  ArrayResize(rt, 6); // добавляет элемент в конец массива
  ArraySetAsSeries(rt, true);
  for (int x = 0; x < ArraySize(rt); x++) {
      Print(rt[x].time);
  }
  Print("=================");
(EURUSD,H1)     1970.01.01 00:09:19 - последний элемент
(EURUSD,H1)     2019.12.13 02:00:00
(EURUSD,H1)     2019.12.13 01:00:00
(EURUSD,H1)     2019.12.13 00:00:00
(EURUSD,H1)     2019.12.12 23:00:00
(EURUSD,H1)     2019.12.12 22:00:00
(EURUSD,H1)     =================