Alexey Navoykov: Приведение double к bool (
даже явное!) - это во-первых, концептуальная ошибка. Не вижу причин, чтобы в нормальном коде такое могло
понадобиться. Во-вторых, приведения вещественных чисел должны производиться через нормализацию - это известно
мало-мальскому программисту. Какое уж тут неявное приведение...
И уж тем более, одно дело инициализация
переменной, когда всё перед глазами. И другое дело, когда вызывается некая функция, находящаяся возможно в
какой-то библиотеке, и тип аргумента этой функции нам не виден. Контроль типов - это залог качества и надёжности кода.
voidOnStart()
{
int i = 1, j = 2;
double d = 10;
bool b = d; // Все нормально, потому что это b = (d != 0);if (b + 1); // Здесь невозможно совершить ошибку, поэтому предупреждение неоправдано.if (d + 1); // Здесь возможна ошибка, поэтому предупреждение оправдано.
d += 1;
// Случай, когда нет однозначного решения, делать предупреждение или нет.// Т.к. эта запись удобна и понятна (см. пример внизу), но все же может быть ошибочной.if (d); // Здесь возможна ошибка только в том случае, если была замена типа переменной с int на double.// Предупреждение частой ошибки, когда клавиша не сработала повторно или не переключился с другого языка.if (i & j); // Здесь мог иметься в виду &&, поэтому предупрежедение может помочь.if (i | j); // Здесь мог иметься в виду ||, поэтому предупрежедение может помочь.if (i ^ j); // Здесь все однозначно, поэтому предупреждение ни к чему.if (i & 1); // Здесь все однозначно, поэтому предупреждение ни к чему.MqlTick Tick[1] = {0};
CopyTicks(_Symbol, Tick, COPY_TICKS_ALL, 0, 1);
if (Tick[0].bid && Tick[0].ask) // Здесь все однозначно, поэтому нет и не должно быть предупреждения.Print("Tick is OK.");
}
Для начала, нужно разделить сферы использования. Выражение в if - это одно (в C++ оно означает явное приведение
выражения к bool, поэтому там и предупреждений нет). А вот
передача
аргумента в функцию (с чего я и начал разговор) - это кардинально другое, и там должно быть всё очень строго. Впрочем, я
считаю, что if тоже надо сделать более строго (и все прочие случаи тоже). До беспощадности C# конечно дело не доводить, но сделать
хотя бы нечто среднее между C++ и C#. Ибо слабая типизация - зло. А все эти "невозможно совершить ошибку" рано или поздно
выходят боком.
if (b + 1); // Здесь невозможно совершить ошибку, поэтому предупреждение неоправдано.
Что вы тогда понимаете под ошибкой вообще? Если b имеет тип bool, то это выражение лишено смысла, а значит вероятней всего вы
перепутали переменную (предполагалось int). Вот это и есть потенциальная ошибка.
bool b = d; // Все нормально, потому что это b = (d != 0);
Что вы тогда понимаете под ошибкой вообще? Если b имеет тип bool, то это выражение лишено смысла, а значит вероятней всего вы
перепутали переменную (предполагалось int). Вот это и есть потенциальная ошибка.
Да, при написании примера допустил невнимательность. Имелся в виду int.
Если бы был bool - там должно было быть предупреждение. Если же взять int, то невозможно совершить ошибку при такой записи. Попробуйте ее
придумать.
Кстати, ещё такой момент, что желательно разделять строгость правил для переменных (менее строго), и для значений функций (более
строго). Ибо переменные у нас перед глазами, их имена обычно дают понять об их типе (а кто-то ещё и венгерку использует), поэтому
ошибиться там сложней:
if (error) ... // Исходя из названия переменной мы понимаем, что запись корректнаif (handle) ... // А здесь, очевидно, запись некорректна
А вот названия функций далеко не всегда дают понимание о возвращаемом типе:
if (File.Open()) ... // Не очевидно, что возвращает функция: true/false или значение хэндла? Т.е. во втором случае у нас будет ошибка, но мы не видим этого
Поэтому для функций желательно сделать требования строже, чем к переменным.
Да что ж вы всё этим даблом! ) Тем более я ж говорю про ужесточение требований в первую очередь к значениям (и передаваемым
аргументам) функций, а не переменных.
Да и эти ваши примеры явно притянуты за уши. Ничто же мешает сделать перегрузку для какого-то конкретного типа, если он не подпадает под
общее правило. Да и вообще такие проверки "разрешаю" для шаблонов должны выполняться методами SFINAE на стадии раскрытия шаблона,
а не внутри, иначе замаетесь потом искать. А коль в MQL нет возможности использовать SFINAE, то нужно делать всё через перегрузки.
Да что ж вы всё этим даблом! ) Тем более я ж говорю про ужесточение требований в первую очередь к значениям (и передаваемым
аргументам) функций, а не переменных.
Пример потенциальной ошибки с функцией приведите, пожалуйста.
Alexey Navoykov:
Да и эти ваши примеры явно притянуты за уши.
Вы предлагаете усложнить жизнь программиста за счет написания огромного количества перегрузок, увеличивая вероятность ошибок во время
этого. И отнимая уйму времени на ерунду.
И все ради чего? Не просто так существуют специальные анализаторы кода, которые выявляют проблемные места куда круче компиляторов.
Вы предлагаете усложнить жизнь программиста за счет написания огромного количества перегрузок, увеличивая вероятность ошибок во
время этого. И отнимая уйму времени на ерунду.
И все ради чего? Не просто так существуют специальные анализаторы кода, которые выявляют проблемные
места куда круче компиляторов.
Ну я лишь предложил нормальное решение. А копаться в глубинах таких универсальных шаблонов, пытаясь понять, почему он был вызван и
главное - откуда - вот это как-раз таки уйма потерянного времени и нервов. Намаялся в своё время, когда тоже страдал этой
паранойей насчёт лишней пары строчек кода. Краткость - далеко не всегда таланта, как показывает практика. Да и про огромное
количество перегрузок речи не шло. Требовалось же перегрузить шаблон лишь для T* и string. Впрочем ладно, это тема не для
данной ветки.
А насчёт анализаторов MQL кода, выявляющих проблемные места, я что-то не слышал. Видел вроде в кодобазе какую-то сырую поделку, но
там далеко до такого.
Эти примеры, кроме File.Open, не являются потенциально ошибочными.
Что касается File.Open, то там предупреждение, возможно, могло сыграть положительную роль.
Ну я лишь предложил нормальное решение. А копаться в глубинах таких обезличенных шаблонов, пытаясь понять, почему он был
вызван и главное - откуда - вот это как-раз таки уйма потерянного времени и нервов. Намаялся в своё время, когда тоже
страдал этой паранойей насчёт лишней пары строчек кода. Краткость - далеко не всегда таланта, как показывает практика.
Шаблоны были приведены в виде "кстати". if (double) наделять предпреждением - причина не ясна. Неудобства видны.
Что касается лаконичности, то полезность от нее только одна - быстрое улавливание сути и недопущение потенциальных ошибок при написании
доп. кода.
А насчёт анализаторов MQL кода, выявляющих проблемные места, я что-то не слышал. Видел вроде в кодобазе какую-то сырую
поделку, но там далеко до такого.
Сделать MQL-код компилируемым в С++. После чего применить анализатор. Понятно, что бывают заковыристые совсем несовместимые случаи. Тогда
игнорить их.
Для авторизации и пользования сайтом MQL5.com необходимо разрешить использование файлов Сookie.
Пожалуйста, включите в вашем браузере данную настройку, иначе вы не сможете авторизоваться.
Вы вошли в аккаунт. Двухфакторная аутентификация отключена. Настройте её заново и отсканируйте новый QR-код или продолжите с отключённой двухфакторной аутентификацией.
Приведение double к bool ( даже явное!) - это во-первых, концептуальная ошибка. Не вижу причин, чтобы в нормальном коде такое могло понадобиться. Во-вторых, приведения вещественных чисел должны производиться через нормализацию - это известно мало-мальскому программисту. Какое уж тут неявное приведение...
И уж тем более, одно дело инициализация переменной, когда всё перед глазами. И другое дело, когда вызывается некая функция, находящаяся возможно в какой-то библиотеке, и тип аргумента этой функции нам не виден. Контроль типов - это залог качества и надёжности кода.
Для начала, нужно разделить сферы использования. Выражение в if - это одно (в C++ оно означает явное приведение выражения к bool, поэтому там и предупреждений нет). А вот передача аргумента в функцию (с чего я и начал разговор) - это кардинально другое, и там должно быть всё очень строго. Впрочем, я считаю, что if тоже надо сделать более строго (и все прочие случаи тоже). До беспощадности C# конечно дело не доводить, но сделать хотя бы нечто среднее между C++ и C#. Ибо слабая типизация - зло. А все эти "невозможно совершить ошибку" рано или поздно выходят боком.
Что вы тогда понимаете под ошибкой вообще? Если b имеет тип bool, то это выражение лишено смысла, а значит вероятней всего вы перепутали переменную (предполагалось int). Вот это и есть потенциальная ошибка.
Такая запись даже глаз режет. Вам нет?
Что вы тогда понимаете под ошибкой вообще? Если b имеет тип bool, то это выражение лишено смысла, а значит вероятней всего вы перепутали переменную (предполагалось int). Вот это и есть потенциальная ошибка.
Да, при написании примера допустил невнимательность. Имелся в виду int.
Если бы был bool - там должно было быть предупреждение. Если же взять int, то невозможно совершить ошибку при такой записи. Попробуйте ее придумать.
Такая запись даже глаз режет. Вам нет?
Не режет. Пример с тиком привел.
Кстати, ещё такой момент, что желательно разделять строгость правил для переменных (менее строго), и для значений функций (более строго). Ибо переменные у нас перед глазами, их имена обычно дают понять об их типе (а кто-то ещё и венгерку использует), поэтому ошибиться там сложней:
А вот названия функций далеко не всегда дают понимание о возвращаемом типе:
Поэтому для функций желательно сделать требования строже, чем к переменным.
Кстати, ещё такой момент
Плохо будет, если на if(double) будет ругаться.
Плохо будет, если на if(double) будет ругаться.
Да что ж вы всё этим даблом! ) Тем более я ж говорю про ужесточение требований в первую очередь к значениям (и передаваемым аргументам) функций, а не переменных.
Да и эти ваши примеры явно притянуты за уши. Ничто же мешает сделать перегрузку для какого-то конкретного типа, если он не подпадает под общее правило. Да и вообще такие проверки "разрешаю" для шаблонов должны выполняться методами SFINAE на стадии раскрытия шаблона, а не внутри, иначе замаетесь потом искать. А коль в MQL нет возможности использовать SFINAE, то нужно делать всё через перегрузки.
Да что ж вы всё этим даблом! ) Тем более я ж говорю про ужесточение требований в первую очередь к значениям (и передаваемым аргументам) функций, а не переменных.
Пример потенциальной ошибки с функцией приведите, пожалуйста.
Да и эти ваши примеры явно притянуты за уши.
Вы предлагаете усложнить жизнь программиста за счет написания огромного количества перегрузок, увеличивая вероятность ошибок во время этого. И отнимая уйму времени на ерунду.
И все ради чего? Не просто так существуют специальные анализаторы кода, которые выявляют проблемные места куда круче компиляторов.
Пример потенциальной ошибки с функцией приведите, пожалуйста.
Я ж уже приводил выше: вот и вот.
Вы предлагаете усложнить жизнь программиста за счет написания огромного количества перегрузок, увеличивая вероятность ошибок во время этого. И отнимая уйму времени на ерунду.
И все ради чего? Не просто так существуют специальные анализаторы кода, которые выявляют проблемные места куда круче компиляторов.
Ну я лишь предложил нормальное решение. А копаться в глубинах таких универсальных шаблонов, пытаясь понять, почему он был вызван и главное - откуда - вот это как-раз таки уйма потерянного времени и нервов. Намаялся в своё время, когда тоже страдал этой паранойей насчёт лишней пары строчек кода. Краткость - далеко не всегда таланта, как показывает практика. Да и про огромное количество перегрузок речи не шло. Требовалось же перегрузить шаблон лишь для T* и string. Впрочем ладно, это тема не для данной ветки.
А насчёт анализаторов MQL кода, выявляющих проблемные места, я что-то не слышал. Видел вроде в кодобазе какую-то сырую поделку, но там далеко до такого.
Я ж уже приводил выше: вот и вот.
Эти примеры, кроме File.Open, не являются потенциально ошибочными.
Что касается File.Open, то там предупреждение, возможно, могло сыграть положительную роль.
Ну я лишь предложил нормальное решение. А копаться в глубинах таких обезличенных шаблонов, пытаясь понять, почему он был вызван и главное - откуда - вот это как-раз таки уйма потерянного времени и нервов. Намаялся в своё время, когда тоже страдал этой паранойей насчёт лишней пары строчек кода. Краткость - далеко не всегда таланта, как показывает практика.
Шаблоны были приведены в виде "кстати". if (double) наделять предпреждением - причина не ясна. Неудобства видны.
Что касается лаконичности, то полезность от нее только одна - быстрое улавливание сути и недопущение потенциальных ошибок при написании доп. кода.
А насчёт анализаторов MQL кода, выявляющих проблемные места, я что-то не слышал. Видел вроде в кодобазе какую-то сырую поделку, но там далеко до такого.
Сделать MQL-код компилируемым в С++. После чего применить анализатор. Понятно, что бывают заковыристые совсем несовместимые случаи. Тогда игнорить их.
Эти примеры, кроме File.Open, не являются потенциально ошибочными.