CERT C: Rule INT34-C

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

Описание

Управляйте определением

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

Реализация Polyspace

Это средство проверки проверяет на эти проблемы:

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

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

Примеры

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

Проблема

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

Риск

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

Фиксация

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

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

Смотрите примеры мер ниже.

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

Пример - Сдвиг отрицательной переменной

int shifting(int val)
{
    int res = -1;
    return res << val;
}

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

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

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

int shifting(int val)
{
    unsigned int res = -1;
    return res << val;
}

Проблема

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

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

Риск

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

Фиксация

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

Можно зафиксировать дефект:

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

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

Смотрите примеры мер ниже.

Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты 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 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.

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

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