#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 могут быть неуместными, и существуют соответствующие механизмы.
Поскольку это является консультативным, возможные меры по смягчению:
- Переместить код — возможно, если код проекта, но не если принятый код
- Просто игнорируйте Правило — это противоречит соблюдению MISRA
- Не одобряйте правило, с обоснованием, например, модульность кода — это часто правильный подход
Как я уже говорил ранее, любой, кто требует 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».