Новая версия платформы MetaTrader 5 build 2980: Push-уведомления о торговых операциях - страница 32
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
это лишь проверка на допустимые значения для типа
мой пример тож компилятор прекрасно отследит:
" просто сравнивает на эквивалентность типов и возможности кастинга к другим типам" - это и значит, что компилятор прекрасно знает тип переменной.
например такой код выдает предупреждение компилятора:
Так что предложение fxsaber не лишено оснований.
Пример синтетический и полностью оптимизируется компилятором методом распространения констант.
То есть, вместо переменной будет чистая константа в условии. И такое вырожденное условие можно на этапе компиляции отловить.
Пример синтетический и полностью оптимизируется компилятором методом распространения констант.
То есть, вместо переменной будет чистая константа в условии. И такое вырожденное условие можно на этапе компиляции отловить.
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Новая версия платформы MetaTrader 5 build 2980: Push-уведомления о торговых операциях
Igor Makanu, 2021.08.23 21:29
проверил совет из статьи, на Вашем примере
так работает при компиляции по F5
К сожалению, так работает совершенно неправильно. добавление +0u приводит min к uint, и -1 тоже приводится к uint, превращаясь в UINT_MAX, поэтому получается выражение
что равно 0 для любого min типа int. (в вашем примере и печатается "i = 0").
Для себя я пришел к такому выводу. Для операций с int и long, чтобы избежать UB из-за переполнения:
1. Для операций +,-,*,"/" с двуми переменными int проще всего привести одну из них к long. А потом, если надо, конвертировать результат в int:
2. Для операций +,-,* с long надо привести одну из переменных к ulong (т.к. эти операции выполняются одинаково для ulong и long кроме флагов - переполняния и знака и тп), а потом результат к long.
3. При делении long/long переполнение, насколько я знаю, может возникнуть только при LONG_MIN/-1 (и результатом возвращается 0). Поэтому нужна такая конструкция:
Удобнее, наверно, сделать функцию (пригодная и для int тоже):
Прошу экспертов поправить, если я где-то ошибаюсь.
P.S. исправил опечатку в примере с long((ulong)l1 + l2)
Для себя я пришел к такому выводу. Для операций с int и long, чтобы избежать UB из-за переполнения:
Просьба оформить в виде скрипта, где на числах показаны проблемные ситуации, которые обходятся.
Хочется иметь памятку в виде кода, где все лаконично продемонстрировано.
Сам сталкивался на MT4 и на MT5 с крутыми поворотами.
А (i==i) можно?
Можно, но это уже дело статических анализаторов типа PVS Studio / CPP Check и аналогичных.
Обычные компиляторы более щадяще относятся к коду, хотя и увеличивают объем анализа.
Просьба оформить в виде скрипта, где на числах показаны проблемные ситуации, которые обходятся.
Хочется иметь памятку в виде кода, где все лаконично продемонстрировано.
Сам сталкивался на MT4 и на MT5 с крутыми поворотами.
Как известно, если результат операции с целыми числами превышает верхнюю границу допустимого диапазона значения для типа, происходит целочисленное переполнение.
По стандарту C++ беззнаковые вычисления выполняются по модулю 2, т.е. при сложении UINT_MAX+2 итоговым результатом операции будет UINT_MAX+2 mod (2^32) == 1, т.е. переход через 0. Это штатная ситуация для беззнаковых целых типов - не UB!
Но для знаковых целых типов такое же переполнение - уже UB в C++ и в mql (как сообщил Ilyas https://www.mql5.com/ru/forum/371494/page29#comment_24202754).
По факту переполнение при сложении/вычитании и умножении int и long работает предсказуемо, например INT_MAX+1 всегда возвращает INT_MIN. Но тем не менее, из-за UB нет гарантии, что так будет всегда и на всех платформах (или я напрасно беспокоюсь и можно спокойно кодить UB?) .
Я знаю пока только один пример непредсказуемого поведения при делении INT_MIN/-1 (и LONG_MIN/-1) - они выдают непостоянные результаты.
Еще одна ситуация - для беззнакового ushort тоже может возникнуть UB. При умножении ushort*ushort может быть UB, т.к. ushort младше int и приводится к int; и может быть переполнение - только при умножении.
Вот примеры того, как можно обойти эти UB, с расширением результата операций до большей разрядности и без:
P.S. В общем-то эти вещи общеизвестные. Есть еще несколько "подводных граблей" с целыми, про которые мало где упомяняют и новички на них рано или поздно наступят. Хочу написать отдельный пост, но позже.
А (i==i) можно?
сравнение double с самой-же double часто используется как тест на валидность. (что оно не специальное представление)
оптимизатор не должен такое вырезать ни при каких условиях и флагах
сравнение double с самой-же double часто используется как тест на валидность. (что оно не специальное представление)
оптимизатор не должен такое вырезать ни при каких условиях и флагах
Вот примеры того, как можно обойти эти UB, с расширением результата операций до большей разрядности и без: