Errores, fallos, preguntas - página 417

 
joo:

sí, si se necesita devolver algo en return().

o al menos para que el compilador esté seguro de que la función devolverá algo:

esto es cierto no sólo para
switch

pero en general, para todas las funciones excepto void

Intenta compilar este código:

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

no compila.

Ahora descompílalo:

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

¡y se producirá un milagro! :)

 
Yedelkin:

Según el Manual, un bool es un tipo especial distinto del entero... Por eso he borrado mi afirmación incorrecta. Aunque no voy a discutir, no soy un experto.

No me refería a las etiquetas de mayúsculas y minúsculas, sino a las enumeraciones (considerando el tipo bool como el más pequeño de ellos). Aquí hay un ejemplo con el mismo error de compilación:

Así que repetiré mi pregunta sobre este ejemplo: ¿quieres decir que el compilador no tiene en cuenta la lista de valores de la enumeración Triple y su número total? Tengo todos los valores de la enumeración utilizados en el operador switch.

Según he entendido el compilador (desarrolladores) está reasegurando. La cuestión es que si una variable no se inicializa explícitamente obtendrá un valor falso/0 dependiendo de su tipo (el segundo se refiere a las enumeraciones).

Pero si obtenemos un valor fuera del rango de variantes posibles (en el ejemplo con Triple puede ser cualquier valor fuera del rango -1 - +1) en la ejecución sin resultado devoultivo habrá serios problemas.

 
Interesting:

¿Qué debe devolver la función si se excluye al moroso?

Creo que el último valor de la enumeración ENUM_CHART_MODE. Lo comprobaré ahora.

...mmm, no funcionó. Imprime lo siguiente: ChartMode=ENUM_CHART_MODE::-1
 
Interesting:

Según tengo entendido, el compilador (los desarrolladores) están reasegurando. La cuestión es que si una variable no se inicializa explícitamente obtendrá un valor falso/0 dependiendo de su tipo (el segundo se refiere a las enumeraciones).

Pero si obtenemos un valor fuera del rango de variantes posibles (en un ejemplo con Triple puede ser cualquier valor fuera del rango -1 - +1) al ejecutar sin resultado devolutivo habrá problemas serios.

No se trata exactamente de eso. Mira mi post anterior.
 
joo:
No se trata exactamente de eso. Mira mi post anterior.

Sí, el compilador tiene que asegurarse de que devuelve algo. Creo que es una garantía razonable (en particular, tener un defecto en el procesamiento del interruptor en el ejemplo).

Otra cosa es que no necesites devolver un valor.

 
Yedelkin:

Creo que el último valor es de la enumeración ENUM_CHART_MODE. Lo comprobaré ahora.

...Sí, no funcionó. Imprime lo siguiente: ChartMode=ENUM_CHART_MODE::-1

Si quieres profundizar en todos estos entresijos, lee a Björn Straustrup, C++.

Para ser honesto, ni siquiera he leído la documentación de MQL5 - sólo estoy escribiendo como en C++. Los desarrolladores siguen con bastante precisión las normas de este lenguaje.

 

¡Buenas tardes!

construye 466.

Empiezo, en cuanto aparece la conexión y se descargan algunos kilobytes, el terminal se cierra. Desconecto el internet - no se cierra.

Adjunto el archivo del directorio /logs/Crash/.

¿Hay alguna solución para este problema?

Gracias

)) no se adjunta. Este es el texto:

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

Programa : Terminal de Cliente

Versión : 500.466 (09 Jun 2011)

Revisión : 32925

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

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

Memoria : 911 libres de 1983 Mb

Virtual : 1815 libre de 2047 Mb

CrashMD5 : 2219A3BB7215B179256A7E41D40BD511

Excepción : C0000094 en 007B41B4 NA a 00000000


Módulos : 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)


Registros : 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 con el tema del uso del operador switch en funciones que devuelven valores. Ayer se obtuvo una conclusión intermedia y se confirmó queel uso de la etiqueta por defecto es obligatorio cuando se utiliza enumeración+conmutación. Pero he aquí un ejemplo en el que se refuta esta conclusión:

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();
  }
Aquí el operador de cambio se aplica dos veces y la etiqueta por defecto se excluye al aplicarlo de nuevo (2º nivel). El mismo operador y el mismo compilador, pero funciona. Asumiendo que el compilador tiene en cuenta la posibilidad de encontrar cualquier basura en las variables triple_var1 y triple_var2 y simultáneamente no considera la lista de valores en la enumeración triple y su número, ¿por qué el compilador no reporta un error en el segundo nivel del operador switch? ¿Nuestras conclusiones/supuestos intermedios eran erróneos o el compilador se limita a comprobar los operadores sólo "en el primer nivel"? En particular, si comentamos la etiqueta/etiquetas de switch(triple_var2), sigue sin haber mensajes de error, aunque la función Test() no es de tipo void.

Se obtiene un resultado similar si se inserta el operador switch(triple_var2) (sin la etiqueta por defecto) después de cualquier etiqueta de caso en el operador switch(triple_var1).

 
Yedelkin:

Continuando con el tema del uso del operador switch en funciones que devuelven valores. Ayer se obtuvo una conclusión intermedia y se confirmó queel uso de la etiqueta por defecto es obligatorio cuando se utiliza enumeración+conmutación. Pero he aquí un ejemplo en el que se refuta esta conclusión:

Aquí el operador de cambio se aplica dos veces, y cuando se aplica de nuevo (segundo nivel), se excluye la etiqueta por defecto. Es el mismo operador y el mismo compilador pero funciona. Suponiendo que el compilador tiene en cuenta la probable presencia de basura en las variables triple_var1 y triple_var2 y simultáneamente no considera la lista de valores de la enumeración triple y su número, ¿por qué el compilador no informa de un error en el segundo nivel de uso del operador switch? ¿Nuestras conclusiones/supuestos intermedios eran erróneos o el compilador se limita a comprobar los operadores sólo "en el primer nivel"? En particular, si comentamos la etiqueta/etiqueta switch(triple_var2), seguirá sin aparecer ningún mensaje de error, aunque la función Test() no sea de tipo void.

Este es nuestro defecto, gracias por encontrarlo, lo arreglaremos. Habrá un error.
Comprobar el interruptor para cubrir todos los valores posibles en caso de que esté más allá de la compilación.
Es interesante como "característica" de MQL5, pensaremos qué hacer.
 
El error ha sido corregido.
"Se ha discutido el chip verificador de interruptores, no es posible implementar un control válido/correcto.
El valor de la expresión del interruptor puede ser cualquier cosa, por ejemplo:

enum EV { v1, v2, };

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