Страницы

Поиск по вопросам

вторник, 2 октября 2018 г.

Можно ли на языках C/C++ определить целочисленное переполнение?

Часто в контексте безопасного программирования упоминают проблему целочисленного переполнения (integer overflow). А возможно ли отловить эту ситуацию в C/C++ коде? Ведь процессоры (по крайней мере x86) имеют среди EFLAGS флаг Overflow Flag, получается, что чисто технически такая возможность имеется, да и оверхэд на проверку флага в регистре не должен быть большим (думается так). Либо проблема в постановке вопроса и переполнение нужно не отлавливать, а не допускать никогда? Значит ли последнее, что целочисленные типы принципиально не подходят для любых вычислений?
P.S. Вопрос возник в связи с тем, что в существующем коде (наблюдаемом мной) широко используется int для арифметических расчетов и ничто не защищает от переполнений, гипотетически они могут остаться незамеченными (логикой). И в большинстве случаев с большой вероятностью все в норме (реальные значения невелики), но иногда...


Ответ

Официально в стандарте языка записано, если я не путаю, что переполнение знаковых целочисленных типов зависит от реализации (может генерироваться исключение, может игнорироваться), а беззнаковых игнорируется - значение приводится в представимый диапазон.
Т.е. получается примерно так - сам C/C++ встроенных переносимых средств обнаружения переполнения не имеет.
Но всегда можно использовать дополнительные методы, которые позволят по данным операндам выяснить, будет ли переполнение при выполнении операции. Масса таких вещей описана в книге Г. Уоррена Алгоритмические трюки для программистов
Ну и как иллюстрация, насколько легко пропустить это переполнение - у Страуструпа в Программирование. Принципы и практика... есть одна программка, в которой вычислялся ряд для ex, что ли - и она у него в разнос шла. Он честно написал, что раньше, мол, я думал, что это связано с потерей точности в double, и вроде даже так и написал в первом издании книги, а потом ко второму изданию дошло, что на самом деле это переполнение целочисленных значений при вычислении факториала. Если уж даже Страуструп... :)

Комментариев нет:

Отправить комментарий