CERT C: Rec. INT00-C

Поймите модель данных, используемую вашей реализацией (реализациями)

Описание

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

Поймите модель данных, используемую вашей реализацией (реализациями). [1]

Примеры

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

Описание

Проблема происходит, когда вы используете основные числовые типы вместо typedefs, которые указывают на размер и со знаком.

Средство проверки правила отмечает использование типов основных данных в объявлениях переменной или объявлениях функции и определениях. Правило осуществляет использование typedef s вместо этого.

Средство проверки правила не отмечает использование основных типов в самих операторах typedef.

Риск

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

Пример - прямое использование основных типов в определениях

typedef unsigned int uint32_t;

int x = 0;       /* Non compliant */
uint32_t y = 0;  /* Compliant */

В этом примере объявление x несовместимо, потому что это использует основной тип непосредственно.

Описание

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

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

Риск

Целочисленное переполнение на целых числах со знаком приводит к неопределенному поведению.

Фиксация

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

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

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

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

Чтобы избежать переполнения в целом, попробуйте один из этих методов:

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

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

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

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

Пример - сложение максимального целого числа

#include <limits.h>

int plusplus(void) {

    int var = INT_MAX;
    var++;             
    return var;
}

В третьем операторе этой функции переменная var увеличена одной. Но значение var является максимальным целочисленным значением, таким образом, int не может представлять один плюс максимальное целочисленное значение.

Исправление — различный тип хранения

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

#include <limits.h>

long long plusplus(void) {

    long long lvar = INT_MAX;
    lvar++;
    return lvar;
}

Описание

Целочисленное постоянное переполнение происходит, когда вы присваиваете время компиляции, постоянное переменной целого числа со знаком, тип данных которой не может разместить значение. n битное целое число со знаком содержит значения в области значений [-2n-1, 2n-1-1].

Например, c является 8-битной переменной char со знаком, которая не может содержать значение 255.

signed char c = 255;

Чтобы определить размеры фундаментальных типов, Средство поиска Ошибки использует вашу спецификацию для Target processor type (-target).

Риск

Поведение по умолчанию для постоянного переполнения может отличаться между компиляторами и платформами. Сохранение постоянного переполнения может уменьшать мобильность вашего кода.

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

Фиксация

Проверяйте, является ли постоянное значение тем, что вы предназначили. Если значение правильно, используйте различное, возможно шире, тип данных для переменной.

Пример - переполнение постоянного от макрорасширения

#define MAX_UNSIGNED_CHAR 255 
#define MAX_SIGNED_CHAR 127

void main() {
    char c1 = MAX_UNSIGNED_CHAR;
    char c2 = MAX_SIGNED_CHAR+1;
}

В этом примере дефект появляется на макросах, потому что по крайней мере одно использование макроса вызывает переполнение. Чтобы воспроизвести эти дефекты, используйте Target processor type (-target), где char подписывается по умолчанию.

Исправление — использует различный тип данных

Одно возможное исправление должно использовать различный тип данных для переменных то переполнение.

#define MAX_UNSIGNED_CHAR 255 
#define MAX_SIGNED_CHAR 127

void main() {
    unsigned char c1 = MAX_UNSIGNED_CHAR;
    unsigned char c2 = MAX_SIGNED_CHAR+1;
}

Описание

Спецификаторы строки формата и несоответствие аргументов происходят, когда спецификаторы формата в функциях отформатированного вывода, таких как printf не совпадают со своими соответствующими аргументами. Например, аргумент типа unsigned long должен иметь спецификацию формата %lu.

Риск

Не сочетайтесь между спецификаторами формата и соответствующим результатом аргументов в неопределенном поведении.

Фиксация

Убедитесь, что спецификаторы формата совпадают с соответствующими аргументами. Например, в этом примере, спецификатор %d не совпадает с аргументом строки, message и спецификатор %s не совпадают с целочисленным аргументом err_number.

  const char *message = "License not available";
  int err_number = ;-4
  printf("Error: %d (error type %s)\n", message, err_number);
Переключение этих двух спецификаторов формата фиксирует проблему. Смотрите спецификации для функции printf для получения дополнительной информации о спецификаторах формата.

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

Пример - печать плавания

#include <stdio.h>

void string_format(void) {

    unsigned long fst = 1;

    printf("%d\n", fst);
}

В операторе printf спецификатор формата, %d, не совпадает с типом данных fst.

Исправление — использует спецификатор длинного формата без знака

Одно возможное исправление должно использовать спецификатор формата %lu. Этот спецификатор совпадает с целочисленным типом unsigned и размером long fst.

#include <stdio.h>

void string_format(void) {

    unsigned long fst = 1;

    printf("%lu\n", fst);
}

Исправление — использует целочисленный аргумент

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

#include <stdio.h>

void string_format(void) {

    unsigned long fst = 1;

    printf("%d\n", (int)fst);
}

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

Группа: Rec. 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". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ВЫРАЗИЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

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