如何从 C 函数返回符合 MISRA 的 const 结构成员的地址?

问题描述 投票:0回答:1

我有一个 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
    限定符(但这也删除了“好的”只读行为)
  • 创建 MISRA 偏差

这个问题还有其他解决方案吗?

我从

block
参数中删除了 const 限定符。 这解决了 MISRA 警告,但代价是失去“只读”功能。

c function pointers constants misra
1个回答
0
投票
如今,

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;
}
© www.soinside.com 2019 - 2024. All rights reserved.