Как исправить целочисленное предупреждение о переполнении - PullRequest
0 голосов
/ 02 мая 2019

У меня есть код, который проверяет, находится ли целое число в диапазоне [−2 ^ 31 + 1, 2 ^ 31 - 1]. Однако во время компиляции выдается целочисленное предупреждение о переполнении.

long int tmp_l = strtol(tokens[8].c_str(),NULL,10);

if (tmp_l >= ( (int32_t)-1 * ( ((int32_t)1<<31) - (int32_t)1) ) && 
        tmp_l <= ( ((int32_t)1 << 31) - (int32_t)1) ) {

    long int in_range = tmp_l;

} else {
    cerr << "ERROR: int not in range. Expected [(-2^31)-1, (2^31)-1]. ";
    cerr << "Found: " << tmp_l << endl;
}
main.cpp:93:51: warning: integer overflow in expression [-Woverflow]
     if (tmp_l >= ((int32_t)-1 * (((int32_t)1<<31) - (int32_t)1) ) &&
                                  ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~

Код компилируется нормально, и я не видел ошибки времени выполнения, связанной с этим предупреждением. Куда я иду не так?

1 Ответ

5 голосов
/ 02 мая 2019

Где я иду не так?

2 ^ 31 - 1 - это наибольшее целое число, представляемое 32-битным целым числом со знаком.Поэтому результат операции 1 << 31, который равен 2 ^ 31, находится за пределами диапазона представимых значений.

Поведение переполнения со знаком не определено.

Как исправить

Вы можете использовать это вместо:

if (tmp_l >= std::numeric_limits<int32_t>::min() + 1
 && tmp_l <= std::numeric_limits<int32_t>::max()
...