Как устранить ошибку MISRA C: 2012, связанную с функцией memcpy? - PullRequest
0 голосов
/ 11 января 2019

Я использую стандартную функцию memcpy, которая объявлена ​​в файле string.h таким образом:

extern void *   memcpy(void *, const void *, size_t);

Дело 1 : Мой код скомпилирован без каких-либо ошибок или предупреждений.

const uint8_t *buff = (uint8_t*)Getbuff();
uint8_t data[3] = {0};
memcpy((void*)data,(const void*)(buff+2),3U);

После проверки MISRA C: 2012 я получаю следующую ошибку MISRA:

выполнение арифметики с указателями посредством сложения [MISRA 2012, правило 18.4, рекомендация] memcpy((void*)data,(const void*)(buff+2),3U);

Дело 2 : Если я исправлю ошибку MISRA в случае 1 следующим образом:

const uint8_t *buff = (uint8_t*)Getbuff();
uint8_t data[3] = {0};
memcpy((void*)data,(const void*)(buff[2]),3U);

Я получаю предупреждение о времени компиляции и другую ошибку MISRA.

Предупреждение о времени компиляции:

cast to pointer from integer of different size

Ошибка MISRA:

явное приведение от 'const UINT8' (он же 'const unsigned char') к 'const void *' [MISRA 2012, правило 11.6, обязательно] memcpy((void*)data,(const void*)(buffer[2]),3U);

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Просто;

memcpy( data, &buff[2], 3u ) ;

И арифметика указателей, и приведение не нужны и противоречат правилам MISRA.

Приведение к типу void* скорее неправильно понимает цель указателя void, и приведение в целом может подавить важные предупреждения, которые в противном случае может выдать компилятор. Получающийся в результате де-беспорядок делает код намного проще для чтения и MISRA-совместимых.

Ваш второй случай также был семантически неверным и не привел бы к правильному поведению - предупреждения не всегда являются просто предупреждениями ; часто они указывают на семантические ошибки. Для компилятора « error » просто означает « не может быть скомпилирован » (синтаксическая ошибка); семантическая ошибка - это ошибка, при которой код не выполняет то, что предполагалось.

0 голосов
/ 11 января 2019

Я думаю, что если вы измените арифметику указателя

buff+2

в первом случае до

&(buff[2])

предупреждение MISRA должно исчезнуть.

Или другими словами: добавьте оператор & в случае 2.

...