Erreurs, bugs, questions - page 417

 
joo:

oui, si quelque chose doit être retourné dans return().

ou au moins pour que le compilateur soit sûr que la fonction retournera quelque chose :

ceci est vrai non seulement pour
switch

mais en général, pour toutes les fonctions sauf void

Essayez de compiler ce code :

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

il ne compile pas.

Maintenant, décompilez-le :

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

et un miracle se produira ! :)

 
Yedelkin:

Selon le manuel, un bool est un type spécial autre que les entiers... C'est pourquoi j'ai supprimé ma déclaration incorrecte. Même si je ne vais pas discuter - je ne suis pas un expert.

Je ne voulais pas parler des étiquettes de casse, mais simplement des énumérations (en considérant le type bool comme le plus petit d'entre eux). Voici un exemple avec la même erreur de compilation:

Je répète donc ma question concernant cet exemple : voulez-vous dire que le compilateur ne prend pas en compte la liste des valeurs de l'énumération Triple et leur nombre total ? J'ai toutes les valeurs de l'énumération utilisées dans l'opérateur switch.

Si j'ai bien compris, le compilateur (les développeurs) se réassure. Le fait est que si une variable n'est pas explicitement initialisée, elle obtiendra une valeur fausse/0 en fonction de son type (le second fait référence aux énumérations).

Mais si nous obtenons une valeur en dehors de l'éventail des variantes possibles (dans l'exemple de Triple, il peut s'agir de n'importe quelle valeur en dehors de l'intervalle -1 - +1) lors de l'exécution sans résultat dévolutif, il y aura de sérieux problèmes.

 
Interesting:

Que doit retourner la fonction si le défaillant est exclu ?

Je pense à la dernière valeur de l'énumération ENUM_CHART_MODE. Je vais le vérifier maintenant.

...mmm, ça n'a pas marché. Imprime ce qui suit : ChartMode=ENUM_CHART_MODE::-1
 
Interesting:

Si je comprends bien, le compilateur (les développeurs) se réassure. Le fait est que si une variable n'est pas explicitement initialisée, elle se verra attribuer une valeur fausse/0 en fonction de son type (la seconde concerne les énumérations).

Mais si nous obtenons une valeur en dehors de la plage des variantes possibles (dans un exemple avec Triple, il peut s'agir de n'importe quelle valeur en dehors de la plage -1 - +1) lors de l'exécution sans résultat dévolutif, il y aura de sérieux problèmes.

Ce n'est pas exactement la question. Regardez mon post précédent.
 
joo:
Ce n'est pas exactement la question. Regardez mon post précédent.

Oui, le compilateur doit s'assurer qu'il renvoie quelque chose. Je pense qu'il s'agit d'une garantie raisonnable (en particulier, le fait d'avoir un traitement par défaut sur le commutateur dans l'exemple).

C'est une autre affaire si vous n'avez pas besoin de retourner une valeur.

 
Yedelkin:

Je pense que la dernière valeur provient de l'énumération ENUM_CHART_MODE. Je vais vérifier maintenant.

...Ouais, ça n'a pas marché. Imprime ce qui suit : ChartMode=ENUM_CHART_MODE::-1

Si vous voulez entrer dans le détail de toutes ces subtilités, lisez Björn Straustrup, C++.

Pour être honnête, je n'ai même pas vraiment lu la documentation de MQL5 - j'écris simplement en C++. Les développeurs suivent assez précisément les normes de ce langage.

 

Bonjour !

construire 466.

Je commence, dès que la connexion apparaît et que quelques kilobytes sont téléchargés, le terminal se ferme. Je déconnecte l'internet - il ne se ferme pas.

Je joins le fichier du répertoire /logs/Crash/.

Existe-t-il une solution à ce problème ?

Merci

)) n'est pas attaché. Voici le texte :

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

Programme : Client Terminal

Version : 500.466 (09 Jun 2011)

Révision : 32925

Système d'exploitation : Windows 7 Professional Service Pack 1 (Build 7601)

Processeurs : 2 x processeurs AMD Athlon 64 X2 Dual Core 5000+.

Mémoire : 911 libre de 1983 Mb

Virtuel : 1815 libre de 2047 Mb

CrashMD5 : 2219A3BB7215B179256A7E41D40BD511

Exception : C0000094 à 007B41B4 NA à 00000000


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


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

 

Nous poursuivons le thème de l'utilisation de l'opérateur de commutation dans les fonctions qui renvoient des valeurs. Hier, une conclusion intermédiaire a été obtenue et a confirmé que l'utilisation de l'étiquette par défaut devient obligatoire lors de l'utilisation de l'énumération+commutateur. Mais voici un exemple où cette conclusion est réfutée :

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();
  }
Ici, l'opérateur de commutation est appliqué deux fois et l'étiquette par défaut est exclue lors de la nouvelle application (2ème niveau). En supposant que le compilateur tienne compte de la possibilité de trouver des déchets dans les variables triple_var1 et triple_var2 et qu'il ne tienne pas compte de la liste des valeurs de l'énumération Triple et de leur nombre, pourquoi le compilateur ne signale-t-il pas une erreur au deuxième niveau de l'opérateur switch ? Nos conclusions/hypothèses intermédiaires étaient erronées ou le compilateur se limite à vérifier les opérateurs uniquement "au 1er niveau" ? En particulier, si nous commentons le label/tags de switch(triple_var2), il n'y a toujours pas de message d'erreur, bien que la fonction Test() ne soit pas de type void.

Un résultat similaire est obtenu si l'opérateur switch(triple_var2) (sans l'étiquette par défaut) est inséré après toute étiquette de cas dans l'opérateur switch(triple_var1).

 
Yedelkin:

Nous poursuivons le thème de l'utilisation de l'opérateur de commutation dans les fonctions qui renvoient des valeurs. Hier, une conclusion intermédiaire a été obtenue et a confirmé que l'utilisation de l'étiquette par défaut devient obligatoire lors de l'utilisation de l'énumération+commutateur. Mais voici un exemple où cette conclusion est réfutée :

Ici, l'opérateur de commutation est appliqué deux fois, et lorsqu'il est appliqué à nouveau (2ème niveau), l'étiquette par défaut est exclue. Il s'agit du même opérateur et du même compilateur mais cela fonctionne. En supposant que le compilateur tienne compte de la présence éventuelle de déchets dans les variables triple_var1 et triple_var2 et qu'il ne tienne pas compte simultanément de la liste des valeurs dans l'énumération triple et de leur nombre, pourquoi le compilateur ne signale-t-il pas une erreur au 2e niveau d'utilisation de l'opérateur switch ? Nos conclusions/hypothèses intermédiaires étaient erronées ou le compilateur se limite à vérifier les opérateurs uniquement "au 1er niveau" ? En particulier, si nous commentons l'étiquette/tags switch(triple_var2), aucun message d'erreur ne sera généré, bien que la fonction Test() ne soit pas de type void.

C'est notre défaut, merci de l'avoir trouvé, nous allons le corriger. Il y aura une erreur.
La vérification de l'interrupteur pour couvrir toutes les valeurs possibles dans le cas est au-delà de la compilation.
C'est intéressant en tant que "fonctionnalité" de MQL5, nous allons réfléchir à ce qu'il faut faire.
 
L'erreur a été corrigée.
" La puce de contrôle des interrupteurs a été discutée, il n'est pas possible d'implémenter un contrôle valide/correct.
La valeur de l'expression de commutation peut être n'importe quoi, par exemple :

enum EV { v1, v2, };

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