Ошибки, баги, вопросы - страница 416

 
Yedelkin:

Так какой смысл указывать default:return(false) если переменная относится к типу bool, который в принципе имеет только два значения, оба из которых использованы в операторе switch? Иными словами, метка default вообще никогда не должна выполниться.

P.S. 1. Кроме того, если придерживаться Вашего подхода, то  метка default из факультативной становится обязательной.

2. Операторы break в обоих вариантах - лишние. 

Оператор switch преобразует Ваш bool_var к целому типу.

И компилятор не обязан знать, что эта переменная имеет два значения. Он же не проводит логический анализ алгоритма.

 
Interesting:

Вы забываете еще об одном моменте - любая переменная может иметь неверное значение либо быть не инициализированной (иметь значение "мусор")...

Я не забываю. Поэтому в моём примере переменная была проинициализирована. Несмотря на это компилятор выдал ошибку.

Пример с bool bool_var=-1 крайне некорректен. Убедитесь сами:

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

Оператор switch преобразует Ваш bool_var к целому типу.

И компилятор не обязан знать, что эта переменная имеет два значения. Он же не проводит логический анализ алгоритма.

С булевыми кстати есть некий удачный вариант, при котором не инициализированная переменная или переменная к примеру со значением -1 будет приведена к значению true/false.

Чего конечно же не произойдет если явно объявить переменную как int.

Yedelkin:

Я не забываю. Поэтому в моём примере переменная была проинициализирована. Несмотря на это компилятор выдал ошибку.

Пример с bool bool_var=-1 крайне некорректен. Убедитесь сами:

Уже убедился, потому и убрал. Но это так сказать случайное везение (считайте как особенность языка).

Но обрабатывая возможную ошибку в блоке switch компилятор не должен разбираться что и как туда подают на вход, поэтому компилятор и считает это ошибкой, а не предупреждением.

 
Dima_S:

И компилятор не обязан знать, что эта переменная имеет два значения. Он же не проводит логический анализ алгоритма.

 Т.е Вы хотите сказать, что компилятор не учитывает список значений из перечисления и их общее количество? 

 
Interesting:

Но обрабатывая возможную ошибку в блоке switch компилятор не должен разбираться что и как туда подают на вход, поэтому компилятор и считает это ошибкой, а не предупреждением.

Промежуточный вывод получается такой: при связке "перечисления+switch" использование  метки default становится обязательным?
 
Yedelkin:

1. bool - это и так "целый тип". Или вы хотите сказать, что в switch идёт приведение к более старшему целочисленному типу.

 2. Т.е Вы хотите сказать, что компилятор не учитывает список значений из перечисления и их общее количество? 

1. bool - это целый тип размером один байт. Приведение идет к типу int, Вы правы.

2. Здесь тоже все правильно написали. Только case это не перечисление, а просто метка для условного ветвления.

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

1. bool - это целый тип размером один байт. Приведение идет к типу int, Вы правы.

По Справочнику bool - особый тип, отличный от целочисленных... Поэтому своё неверное утверждение удалил. Хотя спорить не буду - не спец.

Dima_S:

Yedelkin:

 Т.е Вы хотите сказать, что компилятор не учитывает список значений из перечисления и их общее количество? 

2. Здесь тоже все правильно написали. Только case это не перечисление, а просто метка для условного ветвления.

Я имел в виду не метки case, а именно перечисления (рассматривая тип bool как самый малочисленный их них). Вот пример с той же самой ошибкой компиляции:

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();
  }

 Поэтому повторю вопрос применительно к этому примеру: Вы хотите сказать, что компилятор не учитывает список значений из перечисления Triple  и их общее количество? У меня все значения из перечисления использованы в операторе switch.

 
Yedelkin:
Промежуточный вывод получается такой: при связке "перечисления+switch" использование  метки default становится обязательным?

Представим себе вот такой вариант (кстати, значение 3 не прокатит при явном объявлении значения, а -1 запросто). А вот отсутствие явной инициализации переменной укажет что значение равно тоому что имеет 0 индекс (тут все продумано).

Что должна будет вернуть функция если исключить дефаулный вариант?

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:
Промежуточный вывод получается такой: при связке "перечисления+switch" использование  метки default становится обязательным?

да, если нужно что то вернуть в return().

или хотя бы так, что бы компилятор был уверен, что функция обязательно что то вернет:

bool bool_var=false;
bool Test(void)
  {
   switch(bool_var)
     {
      case  true: return(true);
      case false: return(false);
     }
    return(false);//хотя до сюда ни когда не дойдем, но прописать надо
  }
void OnStart()
  {
   Test();
  }
 
Спасибо всем за науку! Придётся скрепя зубами вставлять дополнительные строчки :)