我正在使用在string.h文件中声明的标准memcpy函数:
extern void * memcpy(void *, const void *, size_t);
Run Code Online (Sandbox Code Playgroud)
案例1:我的代码编译时没有任何错误或警告.
const uint8_t *buff = (uint8_t*)Getbuff();
uint8_t data[3] = {0};
memcpy((void*)data,(const void*)(buff+2),3U);
Run Code Online (Sandbox Code Playgroud)
检查MISRA C:2012后,我收到MISRA错误:
通过添加执行指针算法[MISRA 2012规则18.4,咨询]
memcpy((void*)data,(const void*)(buff+2),3U);
案例2:如果我在案例1中修复了MISRA错误:
const uint8_t *buff = (uint8_t*)Getbuff();
uint8_t data[3] = {0};
memcpy((void*)data,(const void*)(buff[2]),3U);
Run Code Online (Sandbox Code Playgroud)
我收到编译时警告和不同的MISRA错误.
编译时间警告:
cast to pointer from integer of different size
Run Code Online (Sandbox Code Playgroud)
MISRA错误:
从
'const UINT8'(又名'const unsigned char')到'const void *'[MISRA 2012规则11.6,要求]的明确演员表memcpy((void*)data,(const void*)(buffer[2]),3U);
只是;
memcpy( data, &buff[2], 3u ) ;
Run Code Online (Sandbox Code Playgroud)
指针算术和强制转换都是不必要的,与MISRA规则相反.
转换为void*相当误解了void指针的目的,并且通常可以抑制编译器可能以其他方式发出的基本警告.由此产生的去杂波使代码更易于阅读并符合MISRA标准.
你的第二个案例在语义上也是不正确的,并且不会导致正确的行为 - 警告并不总是只是警告 ; 通常它们表示语义错误.对于编译器" 错误 "只是意味着" 无法编译 "(语法错误); 一个语义错误是一个地方的代码没有做什么之意.