предупреждение g ++: сравнение выражения без знака <0 всегда ложно - PullRequest
3 голосов
/ 30 августа 2010

Для компиляции моего кода C ++ я использую флаг -W, который вызывает предупреждение:

предупреждение: сравнение выражения без знака <0 всегда ложно </p>

Я считаю, что это считалось ошибкой и было исправлено в версии GCC 4.3, но я использую GCC 4.1

Код, который явно нарушает правила:

void FieldGroup::generateCreateMessage (const ApiEvent::GroupData &data, omsgstream &result) const {
  dblog << debug;

  // Write out the data fields we care about, in the order they were specified
  for (size_t index = 0; index < fields.size(); ++index) {
    size_t esIndex = clsToES[index];
    if (esIndex < 0 || esIndex >= data.fields.length()) {
      ostringstream buf;
      buf << "Invalid field " << index << " (index in ES data set " << esIndex << ", " << data.fields.length() << " fields returned)";
      throw InvalidDataException (buf.str());
    }
    fields[index].writeData (data.fields[esIndex], result);
  }
}

Предупреждение Я получаю:

dbtempl.cpp: В функции-члене 'void ECONZ :: FieldGroup :: generateCreateMessage (const nz :: co :: econz :: eventServer :: ApiEvent :: GroupData &, ECONZ :: omsgstream &)const ': dbtempl.cpp: 480: предупреждение: сравнение беззнакового выражения <0 всегда ложно </p>

Как я могу предотвратить появление этих предупреждений?Я не хочу снимать флаг -W.

Ответы [ 4 ]

18 голосов
/ 30 августа 2010

Вы тестируете, если положительное значение меньше 0.

A size_t не подписано, поэтому по крайней мере 0.

Это может никогда произойти, икомпилятор оптимизирует ситуацию, просто удалив тест.Предупреждение здесь для того, чтобы сообщить вам, потому что, если кто-то это сделает, это может быть ошибкой.

В вашем случае вы можете просто удалить тест, все должно быть в порядке.

5 голосов
/ 30 августа 2010

size_t - целочисленный тип без знака. Следовательно, компилятор видит, что сравнение < 0 всегда будет ложным (в стандарте указывается обертка дополнения 2 при переполнении). Вы должны исключить это сравнение, поскольку оно не используется (и компилятор, вероятно, не сгенерирует для него никакого кода).

Целые числа без знака, объявленные как без знака, должны подчиняться законам арифметики по модулю 2n, где n - число битов в представлении значения этого конкретного размера целого числа. 46

и соответствующая сноска:

46) Это означает, что без знака арифметика не переполняется, потому что результат, который не может быть представлен результирующий целочисленный тип без знака уменьшено по модулю число, которое является одним больше, чем наибольшее значение, может быть представлен в результате целое число без знака.

2 голосов
/ 30 августа 2010

Восстановить символы esIndex < 0 ||

Эта часть кода абсолютно бессмысленна для машины, поэтому компилятор предупреждает вас: «Вы хотели сделать что-то еще?».

0 голосов
/ 30 августа 2010

Как я могу остановить появление этих предупреждений? Я не хочу удалять флаг -W.

: |

Просто исправьте ваш код, и предупреждение исчезнет ... вот в чем идея ...

Предупреждения помогут вам создать правильный, более чистый и эффективный код.

...