我有一个 C 函数,它获取结构成员的地址并将其作为 void 指针返回。 该函数的第一个参数提供指向该结构的指针。此参数以
const
形式提供,以防止函数修改结构成员。
然而,MISRA 2023 规则 C.11.8 不允许将 const
指针强制转换为指针。
结构类型:
typedef struct {
uint16 ID;
int16 *In;
int16 Out;
int16 V;
int8 sfr;
} GAIN_FIP16;
C 函数:
void* Gain_FiP16_GetAddress(const GAIN_FIP16* block, uint16 elementId)
{
void* addr;
switch (elementId)
{
case 1:
addr = (void*)block->In;
break;
case 2:
addr = (void*)&block->Out;
break;
default:
addr = NULL;
break;
}
return (addr);
}
MISRA 检查员确实抱怨演员阵容
(void*)&block->Out
。
这违反了 MISRA 规则:
转换不得删除任何 const、易失性或 _Atomic 来自指针指向的类型的限定。
据我所知,我确实有以下可能性:
const
限定符(但这也删除了“好的”只读行为)这个问题还有其他解决方案吗?
我从
block
参数中删除了 const 限定符。
这解决了 MISRA 警告,但代价是失去“只读”功能。
void*
很少是任何问题的正确解决方案。 “抛弃 const”不仅从 MISRA 的角度来看是有问题的,而且在标准 C 中也是有问题的,在标准 C 中,如果该值被取消引用并稍后写入,您将面临调用未定义行为的风险。为什么 MISRA 规则存在。
显而易见的解决方案是重写该函数,使其返回一个
const int16*
,就像它一开始就应该做的那样。您还应该摆脱“自制”标准,转而使用标准 C,并使用 int16_t
中的 stdint.h
。
const int16_t* Gain_FiP16_GetAddress (const GAIN_FIP16* block, uint16_t elementId)
{
const int16_t* addr;
switch (elementId)
{
case 1: addr = block->In; break;
case 2: addr = &block->Out; break;
default: addr = NULL; break;
}
return addr;
}