Fehler, Irrtümer, Fragen - Seite 417

 
joo:

ja, wenn in return() etwas zurückgegeben werden muss.

oder zumindest so, dass der Compiler sicher ist, dass die Funktion etwas zurückgeben wird:

dies gilt nicht nur für
switch

aber im Allgemeinen, für alle Funktionen außer void

Versuchen Sie, diesen Code zu kompilieren:

//+----------------------------------------------------------------------------+
//|                                                                  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);
  }
}
//——————————————————————————————————————————————————————————————————————————————

es lässt sich nicht kompilieren.

Entkompilieren Sie es:

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

und ein Wunder wird geschehen! :)

 
Yedelkin:

Laut Handbuch ist bool ein spezieller Typ, der keine ganze Zahl ist... Deshalb habe ich meine falsche Aussage gelöscht. Aber ich will nicht widersprechen - ich bin kein Experte.

Ich meinte nicht Groß-/Kleinschreibung, sondern nur Aufzählungen (wobei der Typ bool der kleinste von ihnen ist). Hier ist ein Beispiel mit demselben Kompilierungsfehler:

Ich wiederhole also meine Frage zu diesem Beispiel: Meinen Sie, dass der Compiler die Liste der Werte aus der Triple-Aufzählung und deren Gesamtzahl nicht berücksichtigt? Ich habe alle Werte aus der Aufzählung im Switch-Operator verwendet.

Wie ich verstanden habe, sind die Compiler (Entwickler) rückversichert. Der Punkt ist, dass eine Variable, die nicht explizit initialisiert wird, je nach Typ einen falschen/0 Wert erhält (der zweite bezieht sich auf Aufzählungen).

Aber wenn wir bei der Ausführung ohne abweichendes Ergebnis einen Wert außerhalb des Bereichs der möglichen Varianten erhalten (im Beispiel mit Triple kann es jeder Wert außerhalb des Bereichs -1 - +1 sein), wird es ernsthafte Probleme geben.

 
Interesting:

Was soll die Funktion zurückgeben, wenn der säumige Zahler ausgeschlossen ist?

Ich denke, der letzte Wert aus der Aufzählung ENUM_CHART_MODE. Ich werde es jetzt überprüfen.

...mmm, es hat nicht funktioniert. Druckt Folgendes: ChartMode=ENUM_CHART_MODE::-1
 
Interesting:

So wie ich es verstehe, sind die Compiler (Entwickler) rückversichert. Der Punkt ist, dass eine Variable, die nicht explizit initialisiert wird, je nach Typ einen falschen/0 Wert erhält (der zweite bezieht sich auf Aufzählungen).

Wenn wir jedoch einen Wert erhalten, der außerhalb des Bereichs der möglichen Varianten liegt (in einem Beispiel mit Triple kann es jeder Wert außerhalb des Bereichs -1 - +1 sein), haben wir ein ernsthaftes Problem, wenn wir die Variable ohne ein eindeutiges Ergebnis ausführen.

Das ist nicht der Punkt. Sehen Sie sich meinen vorherigen Beitrag an.
 
joo:
Das ist nicht der Punkt. Sehen Sie sich meinen vorherigen Beitrag an.

Ja, der Compiler muss sicherstellen, dass er etwas zurückgibt. Ich denke, das ist eine vernünftige Zusicherung (insbesondere, dass im Beispiel eine Standardeinstellung für die Verarbeitung von Schaltern vorgesehen ist).

Eine andere Sache ist es, wenn Sie keinen Wert zurückgeben müssen.

 
Yedelkin:

Ich denke, der letzte Wert stammt aus der Aufzählung ENUM_CHART_MODE. Ich werde es jetzt überprüfen.

...Ja, es hat nicht funktioniert. Druckt folgendes: ChartMode=ENUM_CHART_MODE::-1

Wenn Sie tief in all diese Feinheiten einsteigen wollen, lesen Sie Björn Straustrup, C++.

Um ehrlich zu sein, habe ich nicht einmal die MQL5-Dokumentation wirklich gelesen - ich schreibe nur in C++. Die Entwickler halten sich ziemlich genau an die Standards dieser Sprache.

 

Guten Tag!

466 bauen.

Ich starte, und sobald die Verbindung hergestellt und ein paar Kilobyte heruntergeladen sind, schließt sich das Terminal. Ich trenne die Internetverbindung, aber es lässt sich nicht abschalten.

Ich hänge die Datei aus dem Verzeichnis /logs/Crash/ an.

Gibt es eine Lösung für dieses Problem?

Danke

)) ist nicht beigefügt. Hier ist der Text:

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

Programm : Client-Terminal

Version : 500.466 (09 Jun 2011)

Revision : 32925

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

Prozessoren: 2 x AMD Athlon 64 X2 Dual Core-Prozessor 5000+

Speicher : 911 frei von 1983 Mb

Virtuell : 1815 frei von 2047 Mb

CrashMD5 : 2219A3BB7215B179256A7E41D40BD511

Ausnahme: C0000094 bei 007B41B4 NA bis 00000000


Module : 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)


Register: 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

 

Fortsetzung des Themas der Verwendung von Switch-Operatoren in Funktionen, die Werte zurückgeben. Gestern wurde ein Zwischenfazit gezogen und bestätigt, dassdie Verwendung von Standardetiketten bei der Verwendung von Aufzählung+Schalter obligatorisch wird. Aber hier ist ein Beispiel, in dem diese Schlussfolgerung widerlegt wird:

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();
  }
Hier wird der Umschaltoperator zweimal angewendet und die Standardbeschriftung wird bei der erneuten Anwendung ausgeschlossen (2. Ebene). Derselbe Operator und derselbe Compiler, aber es funktioniert. Angenommen, der Compiler berücksichtigt die Möglichkeit, irgendeinen Müll in den Variablen triple_var1 und triple_var2 zu finden, und berücksichtigt gleichzeitig nicht die Liste der Werte in der Triple-Aufzählung und ihre Anzahl, warum meldet der Compiler keinen Fehler auf der zweiten Ebene des Switch-Operators? Waren unsere vorläufigen Schlussfolgerungen/Annahmen falsch oder beschränkt sich der Compiler darauf, Operatoren nur "auf der 1. Insbesondere, wenn wir das Label/Tag von switch(triple_var2) auskommentieren, gibt es immer noch keine Fehlermeldungen, obwohl die Funktion Test() nicht vom Typ void ist.

Ein ähnliches Ergebnis erhält man, wenn der switch(triple_var2)-Operator (ohne das Standard-Label) nach einem beliebigen Case-Label im switch(triple_var1)-Operator eingefügt wird.

 
Yedelkin:

Fortsetzung des Themas der Verwendung von Switch-Operatoren in Funktionen, die Werte zurückgeben. Gestern wurde ein Zwischenfazit gezogen und bestätigt, dassdie Verwendung von Standardetiketten bei der Verwendung von Aufzählung+Schalter obligatorisch wird. Aber hier ist ein Beispiel, das diese Schlussfolgerung widerlegt:

Hier wird der Switch-Operator zweimal angewendet, und bei der zweiten Anwendung (2. Ebene) wird das Standardetikett ausgeschlossen. Es ist derselbe Operator und derselbe Compiler, aber es funktioniert. Angenommen, der Compiler berücksichtigt das wahrscheinliche Vorhandensein von Müll in den Variablen triple_var1 und triple_var2 und berücksichtigt gleichzeitig nicht die Liste der Werte in der Triple-Aufzählung und ihre Anzahl, warum meldet der Compiler dann nicht einen Fehler auf der zweiten Ebene der Verwendung des Switch-Operators? Waren unsere vorläufigen Schlussfolgerungen/Annahmen falsch oder beschränkt sich der Compiler darauf, Operatoren nur "auf der 1. Insbesondere, wenn wir das Label/Tag switch(triple_var2) auskommentieren, werden keine Fehlermeldungen erscheinen, obwohl die Funktion Test() nicht vom Typ void ist.

Das ist unser Fehler, danke, dass Sie ihn gefunden haben, wir werden ihn beheben. Es wird ein Fehler auftreten.
Die Überprüfung des Schalters, um alle möglichen Werte abzudecken, geht über die Kompilierung hinaus.
Es ist interessant, wie ein MQL5 "Feature", werden wir darüber nachdenken, was zu tun ist.
 
Der Fehler wurde korrigiert.
"Der Schalterprüfungs-Chip wurde diskutiert, es ist nicht möglich, eine Gültig/Falsch-Kontrolle zu implementieren.
Der Wert des Schalterausdrucks kann z. B. beliebig sein:

enum EV { v1, v2, };

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