CERT C: Rule INT34-C

Не сдвигайте выражение на отрицательное число бит или на больше или равное количеству биты, которые существуют в операнде

Описание

Определение правила

Не сдвигайте выражение на отрицательное число бит или на больше или равное количеству биты, которые существуют в операнде.[1]

Реализация Polyspace

Эта проверка проверяет на наличие следующих проблем:

  • Сдвиг отрицательного значения.

  • Переполнение операции сдвига.

Примеры

расширить все

Проблема

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

Риск

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

Зафиксировать

Исправление зависит от первопричины дефекта. Часто детали результата показывают последовательность событий, которые привели к дефекту. Используйте этот список событий, чтобы определить, как сдвигаемая переменная получает отрицательные значения. Вы можете реализовать исправление на любом событии в последовательности. Если сведения о результате не отображают историю событий, можно отследить их с помощью опций правого щелчка в исходном коде и просмотреть предыдущие связанные события. Смотрите также Результаты интерпретации Bug Finder в интерфейсе пользователя Polyspace Desktop.

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

См. примеры исправлений ниже.

Если вы не хотите устранять проблему, добавьте комментарии к своему результату или коду, чтобы избежать другой проверки. Смотрите Адрес Результаты Polyspace через исправления ошибок или обоснования.

Пример - Перемена отрицательной переменной
int shifting(int val)
{
    int res = -1;
    return res << val;
}

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

Коррекция - изменение типа данных

Одной из возможных коррекций является изменение типа данных сдвинутой переменной на беззнаковую. Эта коррекция устраняет бит знака, поэтому перемена влево не меняет знак переменной.

int shifting(int val)
{
    unsigned int res = -1;
    return res << val;
}
Проблема

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

Точное выделение ресурсов хранения для различных типов с плавающей точкой зависит от процессора. См. Target processor type (-target).

Риск

Переполнение операции сдвига может привести к неопределенному поведению.

Зафиксировать

Исправление зависит от первопричины дефекта. Часто детали результата показывают последовательность событий, которые привели к дефекту. Используйте этот список событий, чтобы определить, как переменные в операции shift получают свои текущие значения. Вы можете реализовать исправление на любом событии в последовательности. Если сведения о результате не отображают историю событий, можно отследить их с помощью опций правого щелчка в исходном коде и просмотреть предыдущие связанные события. Смотрите также Результаты интерпретации Bug Finder в интерфейсе пользователя Polyspace Desktop.

Исправить дефект можно путем:

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

  • Проверка значений, которые приводят к переполнению, и выполнение соответствующей обработки ошибок.

См. примеры исправлений ниже.

Если вы не хотите устранять проблему, добавьте комментарии к своему результату или коду, чтобы избежать другой проверки. Смотрите Адрес Результаты Polyspace через исправления ошибок или обоснования.

Пример - Сдвиг целого числа влево
int left_shift(void) {

    int foo = 33;
    return 1 << foo; 
}

В операторе возврата этой функции битовая операция сдвига выполняется со сдвигом 1 foo биты налево. Однако, int имеет только 32 бита, поэтому область значений сдвига должен быть между 0 и 31. Поэтому эта операция сдвига вызывает переполнение.

Коррекция - Различные типы склада

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

long long left_shift(void) {

    int foo = 33;
    return 1LL << foo; 
}

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

Группа: Правило 04. Целые числа (INT)
Введенный в R2019a

[1] Это программное обеспечение было создано MathWorks, включающее фрагменты: «Сайт SEI CERT-C», © 2017 Университет Карнеги Меллон, Веб-сайт SEI CERT-C + + © 2017 Университет Карнеги Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги Меллон, с специального разрешения от его Института программной инженерии.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ МЕЛЛОН И/ИЛИ ЕГО ИНЖЕНЕРНОГО ИНСТИТУТА ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, СОДЕРЖАЩИЙСЯ В НАСТОЯЩЕМ ДОКУМЕНТЕ, ПОСТАВЛЯЕТСЯ НА БАЗИСЕ «КАК ЕСТЬ». УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ, ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, В ОТНОШЕНИИ ЛЮБОГО ВОПРОСА, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИЮ ПРИГОДНОСТИ ДЛЯ ЦЕЛЕЙ ИЛИ КОММЕРЧЕСКОЙ ВЫГОДЫ, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ В ОТНОШЕНИИ СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКИХ ПРАВ.

Это программное обеспечение и связанная с ним документация не были рассмотрены и не одобрены Университетом Карнеги-Меллон или его Институтом программной инженерии.