Errori, bug, domande - pagina 417

 
joo:

sì, se qualcosa deve essere restituito in return().

o almeno in modo che il compilatore sia sicuro che la funzione restituisca qualcosa:

questo è vero non solo per
switch

ma in generale, per tutte le funzioni tranne void

Provate a compilare questo codice:

//+----------------------------------------------------------------------------+
//|                                                                  Scale.mqh |
//|                                             Copyright © 2010, JQS aka Joo. |
//|                                           http://www.mql4.com/ru/users/joo |
//|                                        https://www.mql5.com/ru/users/joo |
//——————————————————————————————————————————————————————————————————————————————
double Scale(double In,double InMIN,double InMAX,double OutMIN,double OutMAX)
{
  if (OutMIN==OutMAX)
    return(OutMIN);
  if (InMIN==InMAX)
    return((OutMIN+OutMAX)/2.0);
  else
  {
    if (In<InMIN)
      return(OutMIN);
    if (In>InMAX)
      return(OutMAX);
    //return(((In-InMIN)*(OutMAX-OutMIN)/(InMAX-InMIN))+OutMIN);
  }
}
//——————————————————————————————————————————————————————————————————————————————

non si compila.

Ora decompilatelo:

//return(((In-InMIN)*(OutMAX-OutMIN)/(InMAX-InMIN))+OutMIN);

e accadrà un miracolo! :)

 
Yedelkin:

Secondo il manuale, un bool è un tipo speciale diverso dall'intero... Ecco perché ho cancellato la mia affermazione errata. Anche se non voglio discutere - non sono un esperto.

Non intendevo etichette di casi, ma solo enumerazioni (considerando il tipo bool come il più piccolo di essi). Ecco un esempio con lo stesso errore di compilazione:

Quindi ripeto la mia domanda su questo esempio: vuoi dire che il compilatore non tiene conto dell'elenco dei valori dell'enumerazione Triple e del loro numero totale? Ho tutti i valori dell'enumerazione usati nell'operatore switch.

Come ho capito il compilatore (gli sviluppatori) stanno riassicurando. Il punto è che se una variabile non è esplicitamente inizializzata, otterrà un valore falso/0 a seconda del suo tipo (il secondo si riferisce alle enumerazioni).

Ma se otteniamo un valore al di fuori della gamma di varianti possibili (nell'esempio con Triple può essere qualsiasi valore al di fuori della gamma -1 - +1) in esecuzione senza risultato devoultive ci saranno seri problemi.

 
Interesting:

Cosa dovrebbe restituire la funzione se l'inadempiente è escluso?

Penso che l'ultimo valore dell'enumerazione ENUM_CHART_MODE. Lo controllerò ora.

...mmm, non ha funzionato. Stampa il seguente: ChartMode=ENUM_CHART_MODE::-1
 
Interesting:

Da quanto ho capito, il compilatore (gli sviluppatori) stanno riassicurando. Il punto è che se una variabile non è esplicitamente inizializzata, otterrà un valore falso/0 a seconda del suo tipo (il secondo si riferisce alle enumerazioni).

Ma se otteniamo un valore al di fuori della gamma di varianti possibili (in un esempio con Triple può essere qualsiasi valore al di fuori della gamma -1 - +1) quando si esegue senza risultato devoultive ci saranno seri problemi.

Non è esattamente questo il punto. Guarda il mio post precedente.
 
joo:
Non è esattamente questo il punto. Guarda il mio post precedente.

Sì, il compilatore deve assicurarsi che restituisca qualcosa. Penso che sia una rassicurazione ragionevole (in particolare, avere un default sull'elaborazione degli interruttori nell'esempio).

È un'altra questione se non avete bisogno di restituire un valore.

 
Yedelkin:

Penso che l'ultimo valore sia quello dell'enumerazione ENUM_CHART_MODE. Ora controllo.

...Sì, non ha funzionato. Stampa il seguente: ChartMode=ENUM_CHART_MODE::-1

Se volete approfondire tutte queste complessità, leggete Björn Straustrup, C++.

Ad essere onesti, non ho nemmeno letto la documentazione di MQL5 - sto solo scrivendo come in C++. Gli sviluppatori seguono piuttosto precisamente gli standard di questo linguaggio.

 

Buon pomeriggio!

costruire 466.

Inizio, appena appare la connessione e si scaricano alcuni kilobyte, il terminale si chiude. Disconnetto internet - non si chiude.

Sto allegando il file dalla directory /logs/Crash/.

C'è una soluzione a questo problema?

Grazie

)) non è attaccato. Ecco il testo:

Tempo : 2011.06.16 10:28 (0:00:11)

Programma: Terminale client

Versione: 500.466 (09 giugno 2011)

Revisione: 32925

OS: Windows 7 Professional Service Pack 1 (Build 7601)

Processori: 2 x AMD Athlon 64 X2 Dual Core Processor 5000+

Memoria: 911 libero di 1983 Mb

Virtuale : 1815 libero di 2047 Mb

CrashMD5 : 2219A3BB7215B179256A7E41D40BD511

Eccezione: C0000094 a 007B41B4 NA a 00000000


Moduli: 00400000 00B96000 terminal.exe (5.0.0.466)

6FDC0000 00027000 wlidnsp.dll (7.250.4225.0)


007B41A0:00014 [007B41B4] #22663 (terminal.exe)

774D58FC:00C74 [774D6570] strcspn (ntdll.dll)

774D58FC:00CAA [774D65A6] strcspn (ntdll.dll)

74A5DC14:000EC [74A5DD00] func_0x74A5DC14 (dbghelp.dll)

74A5E10D:0016E [74A5E27B] SymGetLineFromAddr64 (dbghelp.dll)

74A5F73A:0085A [74A5FF94] func_0x74A5F73A (dbghelp.dll)

74A6189C:000D2 [74A6196E] func_0x74A6189C (dbghelp.dll)

74A5F73A:00A54 [74A6018E] func_0x74A5F73A (dbghelp.dll)

74A5DC14:000EC [74A5DD00] func_0x74A5DC14 (dbghelp.dll)

74A5E10D:0016E [74A5E27B] SymGetLineFromAddr64 (dbghelp.dll)

74A5F73A:0085A [74A5FF94] func_0x74A5F73A (dbghelp.dll)

74A6189C:000D2 [74A6196E] func_0x74A6189C (dbghelp.dll)

74A5F73A:00A54 [74A6018E] func_0x74A5F73A (dbghelp.dll)

774D68C7:000E0 [774D69A7] RtlLogStackBackTrace (ntdll.dll)

774D58FC:004D7 [774D5DD3] strcspn (ntdll.dll)


Registri: EAX=000000000000 EIP=007B41B4 EFLGS=00010246 ES=0023

EBX=000000000000 ESP=0012E2CC EBP=0012E320 FS=003b

ECX=00000000 ESI=04C74C48 CS=001b GS=0000

: EDX=000000000000 EDI=00000007 DS=0023 SS=0023

 

Continuando il tema dell'uso dell'operatore switch nelle funzioni che restituiscono valori. Ieri, è stata ottenuta una conclusione intermedia che ha confermato che l'uso dell'etichetta di default diventa obbligatorio quando si usa enumerazione+switch. Ma ecco un esempio in cui questa conclusione viene smentita:

enum Triple
  {
   err=-1,
   no = 0,
   hay= 1
  };
Triple triple_var1,triple_var2;
Triple Test(void)
  {
   switch(triple_var1)
     {
      case  err: return(err);
      case   no: return(no);
      case  hay: return(hay);
      default:
         switch(triple_var2)
           {
            case  err: return(err);
            case   no: return(no);
            case  hay: return(hay);
           }
     }
  }
void OnStart()
  {
   Test();
  }
Qui l'operatore di commutazione viene applicato due volte e l'etichetta predefinita viene esclusa quando lo si applica di nuovo (2° livello). Stesso operatore e stesso compilatore, ma funziona. Supponendo che il compilatore tenga conto della possibilità di trovare qualsiasi schifezza nelle variabili triple_var1 e triple_var2 e contemporaneamente non consideri l'elenco dei valori in Triple enumeration e il loro numero, perché il compilatore non segnala un errore sul 2° livello dell'operatore switch? Le nostre conclusioni/assunzioni intermedie erano sbagliate o il compilatore si limita a controllare gli operatori solo "al 1° livello"? In particolare, se commentiamo l'etichetta/tags da switch(triple_var2), non ci sono ancora messaggi di errore, anche se la funzione Test() non è di tipo void.

Un risultato simile si ottiene se l'operatore switch(triple_var2) (senza l'etichetta di default) viene inserito dopo qualsiasi etichetta di caso nell'operatore switch(triple_var1).

 
Yedelkin:

Continuando il tema dell'uso dell'operatore switch nelle funzioni che restituiscono valori. Ieri, è stata ottenuta una conclusione intermedia che ha confermato che l'uso dell'etichetta di default diventa obbligatorio quando si usa enumerazione+switch. Ma ecco un esempio in cui questa conclusione viene confutata:

Qui l'operatore switch viene applicato due volte, e quando viene applicato di nuovo (2° livello), l'etichetta predefinita viene esclusa. È lo stesso operatore e lo stesso compilatore ma funziona. Supponendo che il compilatore tenga conto della possibile presenza di spazzatura nelle variabili triple_var1 e triple_var2 e contemporaneamente non tenga conto dell'elenco di valori in Triple enumeration e del loro numero, perché il compilatore non segnala un errore sul 2° livello di utilizzo dell'operatore switch? Le nostre conclusioni/assunzioni intermedie erano sbagliate o il compilatore si limita a controllare gli operatori solo "al 1° livello"? In particolare, se commentiamo l'etichetta/tags switch(triple_var2), non verrà generato alcun messaggio di errore, anche se la funzione Test() non è di tipo void.

Questo è il nostro difetto, grazie per averlo trovato, lo sistemeremo. Ci sarà un errore.
Controllare l'interruttore per coprire tutti i valori possibili nel caso sia oltre la compilazione.
È interessante come "caratteristica" di MQL5, penseremo a cosa fare.
 
L'errore è stato corretto.
"Il chip switch checker è stato discusso, non è possibile implementare un controllo valido/corretto.
Il valore dell'espressione switch può essere qualsiasi cosa, per esempio:

enum EV { v1, v2, };

string Test(void)
  {
   switch(EV(3))
     {
      case v1: return("v1");
      case v2: return("v2");
     }
   return("oops");
  }
  
void OnStart()
  {
   Print(Test());
  }
Motivazione: