exponenta event banner

CERT C: DCL40-C правил

Не создавать несовместимые объявления одной и той же функции или объекта

Описание

Эта проверка деактивируется в анализе Polyspace ® по умолчанию в качестве кода. См. раздел Шашки, деактивированные в Polyspace как анализ кода по умолчанию (Polyspace Bug Finder Access).

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

Не создавайте несовместимые объявления одной и той же функции или объекта. [1 ]

Внедрение Polyspace

Эта проверка проверяет несоответствие объявления.

Примеры

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

Проблема

Несоответствие объявлений происходит, когда объявление функции или переменной не соответствует другим экземплярам функции или переменной.

Риск

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

Подобная проблема может возникнуть при несоответствии описаний функций.

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

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

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

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

Пример - несогласованные объявления в двух файлах

file1.c

int foo(void) {
    return 1;
}

file2.c

double foo(void);

int bar(void) {
    return (int)foo();
}

В этом примере файл 1.c объявляет foo() как возвращающее целое число. В файле 2.c, foo() объявлен как возвращающий двойник. Это различие может вызвать сбой компиляции. Polyspace поднимает дефект на втором экземпляре foo в файле 2.

Коррекция - выравнивание возвращаемых значений функции

Одной из возможных корректировок является изменение описаний функций таким образом, чтобы они совпадали. В этом примере путем изменения объявления foo в файле file2.c для соответствия файлу file1.c дефект исправлен.

file1.c

int foo(void) {
    return 1;
}

file2.c

int foo(void);

int bar(void) {
    return foo();
}
Пример - Несогласованная трасса структуры

test1.c

#include "square.h" 
#include "circle.h" 
struct aCircle circle; 
struct aSquare square;

int main(){ 
    square.side=1; 
    circle.radius=1;
    return 0;
}

test2.c

#include "circle.h" 
#include "square.h" 
struct aCircle circle; 
struct aSquare square;

int main(){ 
    square.side=1; 
    circle.radius=1;
    return 0;
}

circle.h

#pragma pack(1)

extern struct aCircle{ 
    int radius; 
} circle; 

square.h

extern struct aSquare { 
    unsigned int side:1; 
} square;

В этом примере возникает дефект несоответствия объявления square в square.h, потому что Polyspace делает вывод, что square в square.h не имеет того же выравнивания, что и square в test2.c. Эта ошибка возникает из-за #pragma pack(1) оператор circle.h объявляет конкретную центровку. В тесте 2.c circle.h включается перед square.h. Следовательно, #pragma pack(1) оператор circle.h не сбрасывается на выравнивание по умолчанию после aCircle структура. Из-за этого пропуска, test2.c делает вывод, что aSquare square структура также имеет выравнивание 1 байт. Этот дефект может вызвать сбой компиляции.

Исправление - Закрыть выписки по упаковке

Одной из возможных корректировок является сброс выравнивания структуры после aCircle объявление структуры. Для компиляторов GNU ® или Microsoft ® Visual исправьте дефект, добавив #pragma pack() заявление в конце circle.h.

test1.c

#include "square.h" 
#include "circle.h" 
struct aCircle circle; 
struct aSquare square;

int main(){ 
    square.side=1; 
    circle.radius=1;
    return 0;
}

test2.c

#include "circle.h" 
#include "square.h" 
struct aCircle circle; 
struct aSquare square;

int main(){ 
    square.side=1; 
    circle.radius=1;
    return 0;
}

circle.h

#pragma pack(1)

extern struct aCircle{ 
    int radius; 
} circle; 

#pragma pack()

square.h

extern struct aSquare { 
    unsigned int side:1; 
} square;

Другие компиляторы требуют другого #pragma pack синтаксис. Синтаксис см. в документации по компилятору.

Коррекция - используйте Ignore pragma pack directives Выбор

Одной из возможных корректировок является добавление Ignore pragma pack directives для анализа Bug Finder. Если требуется изменить выравнивание структуры для каждой структуры и не требуется видеть дефект несоответствия объявления, используйте эту поправку.

  1. На панели Конфигурация (Configuration) выберите панель Дополнительные параметры (Advanced Settings).

  2. В поле «Прочее» введите -ignore-pragma-pack.

  3. Повторите анализ.

    Устранен дефект несоответствия декларации.

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

Группа: Правило 02. Объявления и инициализация (DCL)
Представлен в R2019a

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

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

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