5.4. Целочисленные операции 1 255
Это решение работает только в архитектурах, где используется представления допол
нения до двойки. Хотя большинство современных платформ используют именно этот вид
представления) лучше не добавлять изл ишние зависимости от платформы. (См. рекомен
дацию The CERT С Secure Coding Standard [ 1 86 ] ) ''MSC 1 4-C. Не добавляйте излишние зави
симости от платформы".) Это решение может также оказаться более дорогостоящим) чем
проверка постусловий, в особенности на процессорах RISC.
Проверка предусловий) обобщеШiая. Приведенный далее код проверяет подозритель
ное сложение для того, чтобы гарантировать, что не произойдет переполнения независимо
от использованного представления чисел.
0 1 s i gned i n t s i l , s i 2 , surn;
02
03 /* Инициализация s i l и s i 2 * /
04
0 5 i f ( ( s i 2 > О & & s i l > INT_МAX - s i 2 ) 1 1
0 6 ( s i 2 < О & & s i l < INT_MIN - s i 2 ) ) {
0 7 / * Обработка ошибки * /
08
09 else {
1 0 sum = s i l + s i 2 ;
11
Это решение более удобочитаемое и более переносимое, но может быть менее эффек
тивным, чем решение, основанное на представлении в формате дополнения до двойки.
Образова1n1е производноrо тШiа из большего. Истинная сумма двух знаковых цело
численных значений шириной w всегда может быть представлена с помощью w + 1 битов,
как показано на рис. 5.7.
Операнды : w бит и 11 •• • 11
+v 11 •• • 1111
Истинная сум ма: w+ 1 бит и+v t 1 1 1 •• • 1111
Рис. 5. 7. Сумма двух знаковых целочислен ных значен ий
В результате выполнение суммирования в тип большего размера всегда успешно. Полу
чающееся значение можно проверить на соответствие диапазону значений перед преобра
зованием в исходный тип меньшего размера.
В общем случае это решение в языке программирования С является зависимым от ре
ализации, поскольку стандарт не гарантирует, что некоторый один стандартный целочис
ленный тип больше другого .
Избежание или обнаружение циклического возврата при сложе1mи. Циклический
возврат может произойти при сложении двух беззнаковых целочисленных значений, если
сумма операндов больше максимального значения, которое может быть сохранено в ре
зультирующем типе. Хотя беззнаковый циклический возврат точно определен в стандарте
С как приведение по модулю, неожиданный возврат может привести к уязвимостям.
Проверка постусловия с помощью флагов состояния. Н а уровне ассемблера х86-32
беззнаковое переполнение может быть обнаружено с помощью команды j с (переход при
переносе) или j пс (переход при отсутствии переноса). Эти команды помещаются после