Erros, bugs, perguntas - página 416

 
Yedelkin:

Então qual é o objectivo de especificar o default:return(false ) se a variável pertence ao tipo bool, que em princípio tem apenas dois valores, ambos utilizados na declaração do interruptor? Por outras palavras, a etiqueta predefinida nunca deve ser executada de todo.

P.S. 1. Além disso, se seguirmos a sua abordagem, então o rótulo padrão torna-se obrigatório em vez de opcional.

2. Os operadores de quebra não têm qualquer significado em ambos os casos.

O operador do interruptor converte o seu bool_var para um tipo inteiro.

E o compilador não tem de saber que esta variável tem dois valores. Não está a analisar o algoritmo logicamente.

 
Interesting:

Esquece mais uma coisa - qualquer variável pode ter um valor inválido ou não ser inicializada (ter um valor "lixo")...

Não me esqueço. Assim, no meu exemplo, a variável foi inicializada. Apesar disso, o compilador gerou um erro.

O exemplo combool_var=-1é extremamente incorrecto. Consulte-o por si próprio:

bool bool_var=-1;
void OnStart()
  {
   Print("bool_var=",bool_var);
  }   
 
Dima_S:

A declaração do interruptor converte o seu bool_var num tipo inteiro.

E o compilador não precisa de saber que esta variável tem dois valores. Não está a analisar o algoritmo de forma lógica.

A propósito, com booleanos, existe uma variante da sorte quando uma variável não inicializada ou uma variável com valor -1, por exemplo, será lançada para verdadeiro/falso.

O que, claro, não acontecerá se declarar explicitamente a variável como int.

Yedelkin:

Não me esqueço. Foi por isso que a variável foi inicializada no meu exemplo. Apesar disso, o compilador gerou um erro.

O exemplo combool_var=-1é extremamente incorrecto. Convença-se a si próprio:

Já estou convencido disso e é por isso que o removi. Mas é uma sorte acidental (considerem-na como uma característica da língua).

Mas ao lidar com um possível erro num bloco de interruptores, o compilador não tem de descobrir o que e como está a ser introduzido, por isso o compilador trata-o como um erro, e não como um aviso.

 
Dima_S:

E o compilador não precisa de saber que esta variável tem dois valores. Não está a fazer uma análise lógica do algoritmo.

Então está a dizer que o compilador não tem em conta a lista de valores na enumeração e o seu número total?

 
Interesting:

Mas ao processar um possível erro num bloco de comutação, o compilador não tem de descobrir o quê e como está a ser introduzido, por isso o compilador trata-o como um erro, não como um aviso.

A conclusão intermédia é a seguinte: a utilização da etiqueta por defeito torna-se obrigatória quando se utilizam enumerações+switch?
 
Yedelkin:

1. bool já é um "tipo inteiro". Ou está a dizer que o interruptor é uma conversão para um tipo inteiro superior.

2. está a dizer que o compilador não tem em conta a lista de valores enuméricos e o seu número total?

1. bool é um tipo inteiro com o tamanho de um byte. A conversão é para int, está certo.

2. Também está aqui. O único caso não é uma enumeração, mas apenas um rótulo de ramificação condicional.

Документация по MQL5: Основы языка / Типы данных / Целые типы / Типы char, short, int и long
Документация по MQL5: Основы языка / Типы данных / Целые типы / Типы char, short, int и long
  • www.mql5.com
Основы языка / Типы данных / Целые типы / Типы char, short, int и long - Документация по MQL5
 
Dima_S:

1. bool é um tipo inteiro de um byte. A conversão vai para o tipo int, está certo.

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

Dima_S:

Yedelkin:

Então quer dizer que o compilador não tem em conta a lista de valores da enumeração e o seu número total?

2. Também o escreveu correctamente aqui. O único caso não é uma enumeração, mas apenas um rótulo para um ramo condicional.

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

enum Triple
  {
   err=-1,
   no = 0,
   hay= 1
  };
Triple triple_var=err;
Triple Test(void)
  {
   switch(triple_var)
     {
      case  err: return(err);
      case   no: return(no);
      case  hay: return(hay);
      //default:return(hay);
     }
  }
void OnStart()
  {
   Test();
  }

Por isso repito 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.

 
Yedelkin:
A conclusão intermédia é a seguinte: a utilização da etiqueta por defeito torna-se obrigatória quando se utiliza enumeração+switch?

Imaginemos desta forma (a propósito, o valor 3 não funciona com declaração explícita de um valor, mas -1 funciona). Mas a ausência de inicialização explícita da variável mostrará que o valor é igual àquele com índice 0 (tudo isto está bem pensado).

O que deve retornar a função se a opção padrão for excluída?

ENUM_CHART_MODE ChartMode = -1;

string Test()
  {
   switch(ChartMode)
     {
      case 0: return("Bars"); break;
      case 1: return("CANDLES"); break;
      case 2: return("LINE"); break;      
      default: return("Unknown");
     }
  }
void OnStart()
{
Comment(Test());
}
 
Yedelkin:
A conclusão intermédia é a seguinte: a utilização da etiqueta por defeito torna-se obrigatória quando se utiliza enumeração+switch?

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

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

bool bool_var=false;
bool Test(void)
  {
   switch(bool_var)
     {
      case  true: return(true);
      case false: return(false);
     }
    return(false);//хотя до сюда ни когда не дойдем, но прописать надо
  }
void OnStart()
  {
   Test();
  }
 
Obrigado a todos vós pela ciência! Terei de moer os meus dentes para colocar linhas extra :)