Данное диагностическое правило основано на руководстве MISRA (Motor Industry Software Reliability Association) по разработке программного обеспечения.
Функция или объект, объявленный однажды с внутренним типом связывания, при повторном объявлении или определении будет также иметь внутреннее связывание. Это может быть неочевидно для разработчика, и поэтому следует явно указывать спецификатор 'static' в каждом объявлении и определении.
Для С++ это правило распространяется только на функции.
Следующий код не соответствует правилу, так как определение не отражает внутренний тип связывания, заданный в объявлении функции 'foo' с помощью ключевого слова 'static':
static void foo(int x); //in header.h
void foo(int x) //in source.cpp
{
....
}
Код в соответствии с правилом должен быть следующим:
static void foo(int x); //in header.h
static void foo(int x) //in source.cpp
{
....
}
В примере, приведенном ниже, определение функции 'foo' со спецификатором класса хранения 'extern' не задает внешний тип связывания, как могло показаться. Тип связывания остается внутренним:
static void foo(int x); //in header.h
extern void foo(int x) //in source.cpp
{
....
}
Такой код разрешен стандартом языка С, но в данном случае вводит в заблуждение разработчика. Правильный вариант с точки зрения MISRA:
extern void foo(int x); //in header.h
extern void foo(int x) //in source.cpp
{
....
}
Подобный пример с глобальной переменной, нарушающий правило MISRA C:
static short y; //in header.h
extern short y = 10; //in source.c
Переменная 'y' будет иметь внутренний тип связывания. Это может быть неочевидным для разработчика. Допустимым вариантом будет:
static short y; //in header.h
static short y = 10; //in source.c
или
extern short y; //in header.h
extern short y = 10; //in source.c
Данная диагностика классифицируется как:
|