Caratteristiche del linguaggio mql5, sottigliezze e tecniche - pagina 152

 
Slava:

Ce n'è uno? Sei sicuro che ce ne sia uno? Su quale sentiero si trova?

Come posso riprodurlo?

Mettete lo script nei preferiti del Navigatore.

void OnStart() {}


Compilare la versione sbagliata.

void OnStart() {} 123


Riavvia il terminale e prova a modificare lo script dai preferiti.

 
Vladimir Simakov:

Sviluppatori. È necessaria una spiegazione. A quale credere? I documenti o l'implementazione? Finora appare un comportamento indefinito.

@fxsaber, non ti consiglio di usarlo prima delle spiegazioni ufficiali, forse lo sistemeranno.

La documentazione è arretrata, sistemiamola.

Non raccomando di inizializzare le variabili statiche con espressioni, se possibile usate una costante.

Perché quando usate un'espressione non costante, il compilatore genera il seguente codice

//--- исходная функция
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);
  }


C'è un overhead, ogni chiamata controllerà il flag __Implicit_myStaticVar_initialized

Per il caso costante, otterrete il seguente codice

//--- исходная функция
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);
  }

Non ci sono spese generali.

 
Ilyas:

Grazie, ora capisco l'overhead.

 
Puoi facilmente scrivere valori di prezzo non normalizzati in caratteri personalizzati. Qui sotto c'è un semplice controllo.
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)
  }
}


Risultato

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 
 
I commenti non relativi a questo argomento sono stati spostati in "Domande dai principianti di MQL5 MT5 MetaTrader 5".
 
RickD:
... La domanda è diversa. Forse c'è un bug in MQL5, dobbiamo affrontarlo, ma rimandarlo all'argomento per i neofiti non aiuta a risolvere rapidamente la situazione.

Si prega di leggere il titolo dell'argomento.

 
Artyom Trishkin:

Si prega di leggere il titolo del thread.

E dove vede la contraddizione? La situazione descritta può essere una caratteristica del linguaggio o un bug. Questo è quello che volevate scoprire.

 
RickD:

E dove vede la contraddizione? La situazione descritta potrebbe essere una caratteristica del linguaggio, o potrebbe essere un bug. Questo è quello che volevate scoprire.

No. Prima si scopre se si tratta di un bug o di una peculiarità - poi si pubblica esattamente, ed esclusivamente una peculiarità. L'argomento riguarda solo le caratteristiche.

 

@Ilyas@Slava@Renat Fatkhullin

mql ha il supporto per parole chiave non documentate per le funzioni

__inline
__forceinline

È ragionevole usarli?
Se sì, quando li accetterà il compilatore?

 

Nella guida di ArrayReverse:

La funzioneArraySetAsSeries() non sposta fisicamente gli elementi dell'array, ma inverte solo la direzione di indicizzazione all'indietro per organizzare l'accesso agli elementi come in unaserie temporale. La funzione ArrayReverse() sposta fisicamente gli elementi dell'array in modo che l'array sia "invertito".

Ma questo codice dimostra il contrario:

  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)     =================
Motivazione: