преобразование между указателем на функцию и другим типом [MISRA 2012, правило 11.1, обязательно] | pclint 9074

Я использую массив указателей на функции, как показано ниже, чтобы избежать использования оператора switch в коде.

void E_func1(void);
void E_func2(void);
void E_func3(void);

void (*pfGetVal[3])() = {
      E_func1,
      E_func2,
      E_func3
}; 

Но при запуске misra (pclint) я получаю следующую ошибку:

преобразование между указателем на функцию и другим типом [MISRA 2012 Правило 11.1, обязательно]

Мне нужно использовать typedef?

Я пробовал, как показано ниже, но не работал.

void (*pfGetVal[3])();  
pfGetVal[0] = E_func1;
pfGetVal[1] = E_func2;
pfGetVal[2] = E_func3;

person kapilddit    schedule 06.01.2021    source источник


Ответы (2)


Пустой список параметров void func () не означает функцию, не принимающую параметров, а функцию, принимающую любые параметры. В языке C форма () является устаревшим стилем и никогда не должна использоваться.

Не путать с C ++, где void func () и void func (void) идентичны.

Некоторые компиляторы допускают неявное преобразование указателей функций стиля () в (void), но они, строго говоря, относятся к разным типам, и средства проверки MISRA-C гораздо более педантичны, чем обычные компиляторы, когда дело касается безопасности типов.

Исправьте это, объявив список указателей функций как void (*pfGetVal[3])(void). Или еще лучше:

typedef void GetVal (void);

GetVal* const pfGetVal[3] = 
{
  E_func1,
  E_func2,
  E_func3
}; 
person Lundin    schedule 07.01.2021

Правильное определение pfGetVal:

void (*pfGetVal[3])(void) = {
      E_func1,
      E_func2,
      E_func3
};

Если вы не собираетесь изменять этот массив во время выполнения программы, вы должны определить его как постоянные данные:

void (* const pfGetVal[3])(void) = {
      E_func1,
      E_func2,
      E_func3
}; 
person chqrlie    schedule 07.01.2021