CERT C++: DCL40-C

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

Описание

Эта проверка деактивирована в Polyspace по умолчанию® по мере анализа You Code. Смотрите Checkers Deactivated in Polyspace как You Code Default Analysis (Polyspace Bug Finder Access).

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

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

Реализация Polyspace

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

Примеры

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

Проблема

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

Риск

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

Аналогичная проблема может возникнуть при несоответствии в объявлениях функций.

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

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

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

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

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

file1.c

int foo(void) {
    return 1;
}

file2.c

double foo(void);

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

В этом примере file1.cpp объявляет foo() как возвращающее целое число. В file2.cpp, foo() объявляется как возврат double. Это различие вызывает дефект во втором образце foo в файле 2.

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

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

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.cpp. Эта ошибка возникает из-за #pragma pack(1) оператор в circle.h объявляет конкретное выравнивание. В test2.cpp, circle.h включается до square.h. Поэтому #pragma pack(1) оператор из circle.h не сбрасывается на выравнивание по умолчанию после aCircle структура. Из-за этого упущения test2.cpp делает вывод, что aSquare square структура также имеет выравнивание 1 байт.

Коррекция - Закрытие операторов по упаковке

Одной из возможных коррекций является сброс выравнивания структуры после aCircle struct. Для GNU® или Microsoft® Визуальные компиляторы, исправьте дефект, добавив #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. Если требуется изменить выравнивание структуры для каждой структуры, и вы не хотите видеть этот Declaration mismatch дефект, используйте эту коррекцию.

  1. На панели Строении выберите панель Advanced Settings.

  2. В Other поле введите -ignore-pragma-pack.

  3. Перезапустите анализ.

    Дефект Declaration mismatch устранен.

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

Группа: 01. Объявления и инициализация (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 Университет Карнеги Меллон, с специального разрешения от его Института программной инженерии.

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

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