exponenta event banner

Переполнение

Арифметическая операция вызывает переполнение

Описание

Эта проверка арифметической операции определяет переполнение результата. Результат этой проверки зависит от того, разрешены ли нефинитные результаты плавания, такие как бесконечность и NaN.

Результат проверки также зависит от заданного режима округления с плавающей запятой. По умолчанию используется режим округления to-nearest. Посмотрите Float rounding mode (-float-rounding-mode).

Нефинитные плавающие элементы не допускаются

По умолчанию не допускаются конечные плавающие элементы. Если результат операции выходит за пределы допустимого диапазона, происходит переполнение. Проверка:

  • Красный, если результат операции выходит за пределы допустимого диапазона.

  • Оранжевый, если результат операции выходит за пределы допустимого диапазона на некоторых путях выполнения.

  • Зеленый, если результат операции не выходит за пределы допустимого диапазона.

Чтобы точно настроить поведение проверки переполнения, используйте эти параметры и укажите аргумент forbid, allow, или warn-with-wrap-around:

Типы данных операндов определяют допустимый диапазон для арифметической операции. Если операция включает два операнда, для определения общего типа данных при проверке используются правила преобразования ANSI ® C. Этот общий тип данных определяет допустимый диапазон.

Некоторые примеры правил преобразования см. в разделе Допущения об неявных преобразованиях типов данных.

Разрешены нефинитные плавающие элементы

Если включен режим проверки, который включает бесконечности и указывает, что проверка должна предупреждать об операциях, создающих бесконечности, проверка выполняется следующим образом:

  • Красный, если операция производит бесконечность на всех путях выполнения, которые считает программное обеспечение, и сами операнды не бесконечны.

  • Оранжевый, если операция производит бесконечность на некоторых путях выполнения, когда сами операнды не бесконечны.

  • Зеленый, если операция не производит бесконечность, если только сами операнды не являются бесконечными.

Если указано, что проверка должна запрещать операции, создающие бесконечности, цвет проверки зависит только от результата операции. Цвет не зависит от операндов.

Чтобы включить этот режим проверки, используйте следующие параметры:

Примеры

развернуть все

void main() {
  int i=1;
  i = i << 30; //i = 2^30
  i = 2*i-2;
}

В этом примере операция 2*i приводит к значению 231. Проверка переполнения при умножении приводит к красной ошибке, поскольку максимальное значение типа int может удерживать 32-разрядный целевой объект 231-1.

void main(void)
 {
   int i;
   int shiftAmount = 1;

   i = 1090654225 << shiftAmount; 
 }

В этом примере возникает ошибка переполнения при выполнении сдвига влево для целого числа со знаком.

#include <float.h>

void main() {
 float val = FLT_MAX;
 val = val * 2 + 1.0;
}

В этом примере: FLT_MAX является максимальным значением, которое float может представлять на 32-разрядном целевом объекте. Поэтому операция val * 2 приводит к ошибке переполнения.

void func(void) {
   float fVal = -2.0f;
   unsigned int iVal = (unsigned int)fVal; 
}

В этом примере красная проверка переполнения отображается на примере из float кому unsigned int. В соответствии со стандартом C99 (сноска к пункту 6.3.1.4) диапазон значений, которые могут быть преобразованы из значений с плавающей запятой в целые числа без знака при сохранении переносимости кода, составляет (-1, MAX + 1). Для значений с плавающей запятой за пределами этого диапазона преобразование в беззнаковые целые числа определено неправильно. Здесь, MAX - максимальное число, которое может быть сохранено целым типом без знака.

Даже если ошибка во время выполнения не возникает при выполнении кода на целевом объекте, приведение может завершиться сбоем на другом целевом объекте.

Исправление - Приведение к подписанному целочисленному первому

Одним из возможных решений является приведение значения с плавающей запятой к целому числу со знаком. В этом случае целое число со знаком может быть преобразовано в целое число без знака. Для этих слепков правила преобразования четко определены.

void func(void) {
   float fVal = -2.0f;
   int iValTemp = (int)fVal;
   unsigned int iVal = (unsigned int)iValTemp; 
}
#define FLT_MAX 3.40282347e+38F

void float_negative_overflow() {
   float min_float = -FLT_MAX;
   min_float = -min_float * min_float;
}

В float_negative_overflow, min_float содержит наибольшее отрицательное число, что тип float может представлять. Потому что операция -min_float * min_float создает число, которое больше отрицательного, чем это число, тип float не может представлять его. Проверка переполнения приводит к появлению красной ошибки.

#include <stdio.h>

struct
{
  unsigned int dayOfWeek : 2;
} Week;

void main()
{
  unsigned int two = 2, three = 3, four = 4;
  Week.dayOfWeek = two;
  Week.dayOfWeek = three;
  Week.dayOfWeek = four;
}

В этом примере: dayOfWeek занимает 2 бита. Это может принимать значения в [0,3] потому что это целое число без знака. При присвоении значения 4 dayOfWeek, проверка переполнения красного цвета.

Чтобы обнаружить переполнения для подписанных и неподписанных целых чисел, на панели Конфигурация (Configuration) в разделе Проверить поведение (Check Behavior) выберите forbid или warn-with-wrap-around для режима переполнения для целого числа со знаком и для режима переполнения для целого числа без знака.

Результаты в forbid режим:

double func(void) {
    double x=1.0/0.0;
    return x;
}
В этом примере оба операнда / операция не бесконечна, но результатом является бесконечность. Проверка переполнения на - операция красного цвета. В forbid проверка прекращается после проверки красным цветом. Например, неинициализированная проверка локальной переменной не отображается на x в return заявление. Если не включить опцию Разрешить несграничные плавающие элементы, появится проверка Деление на ноль (Division by zero), поскольку бесконечности не разрешены.

Результаты в warn-first режим:

double func(void) {
    double x=1.0/0.0;
    return x;
}
В этом примере оба операнда / операции не бесконечны, но результатом является бесконечность. Проверка переполнения на - операция красного цвета. Красный цвет возвращается warn-first отличаются от красных чеков для других типов чеков. Проверка не прекращается после красной проверки. Например, зеленая неинициализированная проверка локальной переменной появляется на x в return заявление. В результате проверки, если установить курсор на x, вы видите, что он имеет значение Inf.

Результаты в forbid режим:

void func(double arg1, double arg2) {
    double ratio1=arg1/arg2;
    double ratio2=arg1/arg2;
}
В этом примере значения arg1 и arg2 неизвестны для проверки. Проверка предполагает, что arg1 и arg2 может иметь все возможные double значения. Например, arg1 может быть ненулевым и arg2 может быть равен нулю и результатом ratio1=arg1/arg2 может быть бесконечностью. Поэтому в операции разделения появляется оранжевая проверка переполнения. После проверки проверка завершает поток выполнения, который приводит к бесконечности. Проверка предполагает, что arg2 не может быть нулевым после оранжевой проверки. Проверка переполнения во второй секции ratio2=arg1/arg2 зеленый.

Результаты в warn-first режим:

void func(double arg1, double arg2) {
    double ratio1=arg1/arg2;
    double ratio2=arg1/arg2;
}
В этом примере значения arg1 и arg2 неизвестны для проверки. Проверка предполагает, что arg1 и arg2 может иметь все возможные double значения. Например, arg1 может быть ненулевым и arg2 может быть равен нулю и результатом ratio1=arg1/arg2 может быть бесконечностью. В операции разделения появляется оранжевая проверка переполнения. Оранжевый возвращается warn-first режим отличается от оранжевых чеков для других типов чеков. После проверки проверка не завершает поток выполнения, который приводит к бесконечности. Проверка сохраняет нулевое значение arg2 после проверки оранжевого цвета. Поэтому проверка переполнения во второй операции разделения ratio2=arg1/arg2 также оранжевый.

Проверить информацию

Группа: Числовые
Язык: C | C++
Акроним: OVFL