Как мне решить правило 8.7 MISRA-C?

#c #misra

Вопрос:

misra_c_2012_rule_8_7_ насилие

Функция «cpvqResponse» имеет внешнюю связь, но используется только в одной единице перевода.

Комментарии:

1. Что вы пробовали? Какие исследования вы провели? Как вы думаете, как вы можете это решить? Исходя из простой логики, вы можете сделать представленное утверждение неверным, поэтому вы можете: удалить функцию cpvqResponse, или изменить связь функции, или использовать функцию более чем в одной единице перевода.

2. Объявите функцию, как static в файле, в котором она определена/используется.

3. Шарон, есть ли cpvqResponse() объявление в файле включения? Если нет, сделайте один.

4. Ну, это объявлено во включенном файле.

5. Можете ли вы расширить вопрос, чтобы показать объявление, определение и использование (или, по крайней мере, пример минимальной эквивалентности)?

Ответ №1:

Это означает, что должны быть объявлены функции, которые не доступны за пределами одного конкретного файла .c, но используются только в этом файле static . Что совершенно разумно делать во всех программах на языке Си, независимо от MISRA-C.

Комментарии:

1. «внутренний api», правильно!

2. Это не совсем правильно. Это правило также применяется к функциям, которые вы определяете в одном файле (например, функция XY_Init в каком-либо драйвере), которая используется в другом файле. Не всегда есть возможность переместить эту функцию в другой файл и сделать ее там статичной.

3. @Gerhardh Определение функций в заголовочных файлах проблематично и вызывает проблемы с другими правилами MISRA. Этого следует избегать, за исключением нескольких исключений, когда у вас должны быть небольшие static inline функции и т. Д.

4. Я не говорю о заголовках. Вы реализуете некоторый драйвер в файле 1.c, среди прочего, некоторую функцию driver_Init (). Эта функция инициализирует статические объекты внутри этого файла1.c. Если эта функция вызывается только из одного другого файла единицы перевода2.c, генерируется предупреждение MISRA для driver_init (). Вы не можете сделать его статичным в файле 1.c, и вы также не можете перейти в файл 2.c.

5. @Gerhardh Если бы они были логически независимы, вы бы не стали звонить через эти «независимые» единицы перевода, не так ли? Кроме того, как вы вообще вызываете функцию в другой единице перевода без использования внешней связи или определения функции в заголовке?

Ответ №2:

Собрав воедино все комментарии, я понимаю, что ваш код выглядит примерно так:

библиотека.c

 void cpvqResponse( void )
{
    ...
}
 

библиотека.h

 extern void cpvqResponse( void );
 

проект.c

    void main( void )
   {
       ...
       cpvqResponse();
       ...
   }
 

MISRA C:Правило 8.7 2012 года является консультативным руководством и направлено на повышение согласованности и уменьшение взаимосвязи между вашими единицами перевода.

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

Поскольку это является консультативным, возможные меры по смягчению:

  1. Переместить код — возможно, если код проекта, но не если принятый код
  2. Просто игнорируйте Правило — это противоречит соблюдению MISRA
  3. Не одобряйте правило, с обоснованием, например, модульность кода — это часто правильный подход

Как я уже говорил ранее, любой, кто требует 100% соответствия требованиям MISRA, без каких-либо отклонений (или неодобрения), не прочитал и не понял руководство.

[См. Профиль для участия]

Отредактировано, чтобы добавить

Конечно, основная цель этого правила состоит в том, чтобы уловить локальные определения с внешней связью:

мой файл.c

 void myfunc( void );  // Only used internally, should be **static**

void myfunc( void )
{
   ...
}

void main( void )
{
   ...
   myfunc();
   ...
}
 

Комментарии:

1. Спасибо! это отличное объяснение.

2. Помимо MISRA-C, отсутствие использования частной инкапсуляции локальных функций-это то, на что укажет любой приличный обзор кода (и инструмент анализа). Так что это не столько проблема MISRA-C, сколько проблема «написать правильный C».