CERT C: правило DCL36-C

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

Описание

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

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

Примеры

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

Описание

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

Средство проверки правила обнаруживает ситуации где:

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

  • Та же функция объявлена и задана с различными спецификаторами устройства хранения данных.

Риск

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

В этой ситуации связь следует за более ранней спецификацией, которая видима (Стандарт C99, Раздел 6.2.2). Например, если более ранняя спецификация указывает на внутреннюю связь, объект имеет внутреннюю связь даже при том, что последняя спецификация указывает на внешнюю связь. Если вы заметите одну только последнюю спецификацию, вы можете ожидать в противном случае.

Пример - конфликт связи между объявлениями переменной

static int foo = 0;
extern int foo;         /* Non-compliant */

extern int hhh;
static int hhh;         /* Non-compliant */

В этом примере первая строка задает foo с внутренней связью. Первая строка совместима, потому что пример использует ключевое слово static. Вторая строка не использует static в объявлении, таким образом, объявление несовместимо. Для сравнения третья строка объявляет hhh с ключевым словом extern, создающим внешнюю связь. Четвертая строка объявляет hhh с внутренней связью, но это объявление конфликты с первым объявлением hhh.

Исправление — сопоставимый static и использование extern

Одно возможное исправление должно последовательно использовать static и extern:

static int foo = 0;
static int foo;

extern int hhh;
extern int hhh;

Пример - конфликт связи между объявлением функции и определением

static int fee(void);  /* Compliant - declaration: internal linkage */
int fee(void){         /* Non-compliant */
  return 1;
}

static int ggg(void);  /* Compliant - declaration: internal linkage */
extern int ggg(void){  /* Non-compliant */
  return 1 + x;
}

Этот пример показывает два внутренних нарушения связи. Поскольку fee и ggg имеют внутреннюю связь, необходимо использовать спецификатор класса static, чтобы быть совместимыми с MISRA®.

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

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

Введенный в 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". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ВЫРАЗИЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

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