Erros, bugs, perguntas - página 417

 
joo:

sim, se algo precisa de ser devolvido em troca().

ou pelo menos para que o compilador tenha a certeza de que a função irá devolver algo:

isto é verdade não só para
switch

mas em geral, para todas as funções excepto as nulas

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

não se compila.

Agora descompila-a:

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

e um milagre vai acontecer! :)

 
Yedelkin:

De acordo com o Manual, um bool é um tipo especial para além do inteiro. Foi por isso que apaguei a minha declaração incorrecta. Embora não vá discutir - não sou um especialista.

Não me referia a etiquetas de caixa, mas apenas enumerações (considerando o tipo bool como o mais pequeno deles). Aqui está um exemplo com o mesmo erro de compilação:

Então vou repetir a minha pergunta sobre este exemplo: quer dizer que o compilador não tem em conta a lista de valores da enumeração Tripla e o seu número total? Tenho todos os valores da enumeração utilizados no operador de comutação.

Tal como entendi, o compilador (desenvolvedores) está a restabelecer-se. A questão é que se uma variável não for explicitamente inicializada receberá um valor falso/0 dependendo do seu tipo (o segundo refere-se a enumerações).

Mas se obtivermos um valor fora da gama de possíveis variantes (por exemplo com Triplo pode ser qualquer valor fora da gama -1 - +1) em execução sem resultado desonesto, haverá sérios problemas

 
Interesting:

O que deve retornar a função se o incumpridor for excluído?

Penso que o último valor da enumeração ENUM_CHART_MODE. Vou verificá-lo agora.

...mmm, não funcionou. Imprime o seguinte: ChartMode=ENUM_CHART_MODE::-1
 
Interesting:

Tanto quanto sei, o compilador (desenvolvedores) está a restabelecer-se. A questão é que se uma variável não for explicitamente inicializada, ser-lhe-á atribuído um valor false/0 dependendo do seu tipo (o segundo diz respeito às enumerações).

Mas se obtivermos um valor fora da gama de possíveis variantes (num exemplo com Triplo pode ser qualquer valor fora da gama -1 - +1), teremos um grave problema ao executar a variável sem qualquer resultado devoto.

Não é exactamente essa a questão. Vejam o meu post anterior.
 
joo:
Não é exactamente essa a questão. Vejam o meu post anterior.

Sim, o compilador tem de se certificar de que devolve algo. Penso que isto é uma garantia razoável (em particular, ter uma falha no processamento do interruptor no exemplo).

É outra questão, se não precisar de devolver um valor.

 
Yedelkin:

Penso que o último valor é da enumeração ENUM_CHART_MODE. Vou verificar isso agora.

...Sim, não funcionou. Imprime o seguinte: ChartMode=ENUM_CHART_MODE::-1

Se quiser aprofundar todas estas complexidades, leia Björn Straustrup, C++.

Para ser honesto, nem sequer li a documentação MQL5 - estou apenas a escrever como em C++. Os criadores seguem com bastante precisão os padrões desta língua.

 

Boa tarde!

construir 466.

Começo, assim que a ligação aparece e alguns kilobytes são descarregados, o terminal fecha. Desligo a Internet - não fecha.

Estou a anexar o ficheiro do directório /logs/Crash/.

Haverá uma solução para este problema?

Obrigado

)) não está anexado. Aqui está o texto:

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

Programa : Terminal do Cliente

Versão : 500.466 (09 Jun 2011)

Revisão : 32925

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

Processadores : 2 x AMD Athlon 64 X2 Processador de núcleo duplo 5000+

Memória : 911 livre de 1983 Mb

Virtual : 1815 grátis de 2047 Mb

CrashMD5 : 2219A3BBB7215B179256A7E41D40BD511

Excepção : C0000094 em 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)


Registos : 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 o tema da utilização do operador de comutação em funções que retornam valores. Ontem foi obtida uma conclusão intermédia e confirmada que autilização da etiqueta por defeito se torna obrigatória quando se utiliza enumeração+switch. Mas aqui está um exemplo quando esta conclusão é desmentida:

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();
  }
Aqui o operador do interruptor é aplicado duas vezes e a etiqueta predefinida é excluída ao aplicá-la novamente (2º nível). O mesmo operador e o mesmo compilador, mas funciona. Assumindo que o compilador tem em conta a possibilidade de encontrar qualquer lixo nas variáveis triple_var1 e triple_var2 e simultaneamente não considera a lista de valores na enumeração Tripla e o seu número, porque é que o compilador não reporta um erro no segundo nível do operador de comutação? As nossas conclusões/premissas intermédias estavam erradas ou o compilador limita-se a verificar os operadores apenas "no 1º nível"? Em particular, se comentarmos a etiqueta/tags do switch(triple_var2), ainda não há mensagens de erro, embora a função Test() não seja do tipo void().

Um resultado semelhante é obtido se o operador switch(triple_var2) (sem a etiqueta padrão) for inserido depois de qualquer etiqueta no operador switch(triple_var1).

 
Yedelkin:

Continuando o tema da utilização do operador de comutação em funções que retornam valores. Ontem, foi obtida uma conclusão intermédia que confirma que autilização do rótulo por defeito se torna obrigatória quando se utiliza enumeração+switch. Mas aqui está um exemplo em que esta conclusão é refutada:

Aqui o operador do interruptor é aplicado duas vezes, e quando é aplicado repetidamente (2º nível), a etiqueta predefinida é excluída. Assumindo que o compilador tem em conta a presença provável de lixo nas variáveis triple_var1 e triple_var2 e simultaneamente não considera a lista de valores na enumeração Tripla e o seu número, porque é que o compilador não reporta um erro no segundo nível de utilização do operador de comutação? As nossas conclusões/premissas intermédias estavam erradas ou o compilador limita-se a verificar os operadores apenas "no 1º nível"? Em particular, se comentarmos a etiqueta/tags switch(triple_var2), não aparecerão mensagens de erro, embora a função Test() não seja do tipo void().

Esta é a nossa falha, obrigado por a encontrarmos, vamos corrigi-la. Haverá um erro.
A verificação do interruptor para cobrir todos os valores possíveis no caso de estar para além da compilação.
É interessante como uma "característica" MQL5, vamos pensar sobre o que fazer.
 
O erro foi corrigido.
"O chip verificador do interruptor foi discutido, não é possível implementar um controlo válido/correto.
O valor da expressão do interruptor pode ser qualquer coisa, por exemplo:

enum EV { v1, v2, };

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