Приведет ли когда-нибудь «сравнение между целочисленными выражениями со знаком и без знака» в действительности к ошибкам?

Часто объект, который я использую, будет иметь (подписанный) int параметры (например, int iSize) которые в конечном итоге хранят, насколько большим должно быть что-то. В то же время я часто буду инициализировать их -1 чтобы показать, что объект (и т. д.) не был настроен / не был заполнен / не готов к использованию.

Я часто заканчиваю с предупреждением comparison between signed and unsigned integerкогда я делаю что-то вроде if( iSize >= someVector.size() ) { ... },

Таким образом, я номинально не хочу использовать unsigned int, Есть ли ситуации, когда это приведет к ошибке или неожиданному поведению?

Если нет: как лучше всего справиться с этим? Если я использую флаг компилятора -Wno-sign-compare Я мог (гипотетически) пропустить ситуацию, в которой я должен использовать unsigned int (или что-то типа того). Так что я должен просто использовать приведение при сравнении с unsigned int—например. if( iSize >= (int)someVector.size() ) { ... } ?

8

Решение

Да, есть и очень тонкие. Если вам интересно, вы можете проверить эта интересная презентация Стефан Т. Лававей об арифметическом преобразовании и ошибке в реализации Microsoft STL, которая была вызвана только при сравнении со знаком и без знака.

В общем, проблема связана с тем фактом, что из-за арифметики дополнения 2 очень маленькое отрицательное целочисленное значение имеет такое же битовое представление, что и очень большое целое число без знака (например, -1 = 0xFFFF = 65535).

В конкретном случае проверки size()почему бы не использовать тип size_t за iSize на первом месте? Беззнаковые значения просто придают вам большую выразительность, используйте его.

И если вы не хотите объявлять iSize как size_tПросто дайте понять с помощью явного приведения, что вы знаете природу этого сравнения. Компилятор пытается оказать вам услугу с этими предупреждениями, и, как вы правильно написали, могут быть ситуации, когда их игнорирование может вызвать очень сильную головную боль.

Таким образом, если iSize иногда отрицателен (и должен оцениваться как менее чем все unsigned int значения size()), используйте идиому: if ((iSize < 0) || ((unsigned)iSize < somevector.size())) ...

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]