(Как) вы обрабатываете возможные целочисленные переполнения в коде C ++?

Время от времени, особенно при выполнении 64-битных сборок некоторой базы кода, я замечаю, что существует множество случаев, когда возможно целочисленное переполнение. Чаще всего я делаю что-то вроде этого:

// Creates a QPixmap out of some block of data; this function comes from library A
QPixmap createFromData( const char *data, unsigned int len );

const std::vector<char> buf = createScreenShot();
return createFromData( &buf[0], buf.size() ); // <-- warning here in 64bit builds

Дело в том, что std :: vector :: size () красиво возвращает size_t (что составляет 8 байтов в 64-битные сборки), но функция принимает unsigned int (который по-прежнему составляет всего 4 байта в 64-битных сборках). Так что компилятор предупреждает правильно.

Если возможно, я пытаюсь исправить подписи, чтобы использовать правильные типы в первую очередь. Однако я часто сталкиваюсь с этой проблемой при объединении функций из разных библиотек, которые я не могу изменить. К сожалению, я часто прибегаю к некоторым рассуждениям типа «Хорошо, никто никогда не сделает снимок экрана, генерирующий более 4 ГБ данных, так зачем беспокоиться», и просто меняю код на do

return createFromData( &buf[0], static_cast<unsigned int>( buf.size() ) );

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

assert( buf.size() < std::numeric_limits<unsigned int>::maximum() );

Это уже немного лучше, но мне интересно: как вы справляетесь с такого рода проблема, а именно: целочисленные переполнения, которые «почти» невозможны (на практике). Я полагаю, это означает, что они не происходят для вас, они не происходят для QA - но они взрываются перед лицом клиента.

6
задан Frerich Raabe 26 July 2011 в 07:24
поделиться