gpt4 book ai didi

c - 为什么 MISRA-C :2004 throw an error here?

转载 作者:行者123 更新时间:2023-11-30 15:25:35 26 4
gpt4 key购买 nike

我似乎不断收到以下代码片段中 lShift 分配的 MISRA-C:2004 规则 10.1 和 10.3 错误,并且无法真正看到还可以做些什么来满足要求...为什么我仍然收到错误?

#define ADC_INTSELxNy_LOG2_NUMBITS_PER_REG 3U
#define ADC_INTSELxNy_NUMBITS_PER_REG 8U
void foo (const bar_e intNumber) {
uint_least8_t lShift = (uint_least8_t)(ADC_INTSELxNy_NUMBITS_PER_REG - (((((uint_least8_t)intNumber) + 1U) & 0x1U) << ADC_INTSELxNy_LOG2_NUMBITS_PER_REG));
//...
}

最佳答案

那行代码乱七八糟,难以辨认。考虑将其拆分以增加可读性。根据系统上 int 的宽度,代码看起来会有所不同。下面的代码假定 32 位整数。

uint8_t        bit      = (uint8_t)( ((uint32_t)intNumber + 1U) & 0x1U );
uint32_t lShift32 = ((uint32_t)bit << ADC_INTSELxNy_LOG2_NUMBITS_PER_REG);
uint_least8_t lShift8 = (uint_least8_t)((uint32_t)ADC_INTSELxNy_NUMBITS_PER_REG - lShift);

现在至于出现错误的原因,规则 10.1 和 10.3 涉及隐式整数类型提升。如果您像上面那样拆分代码,您将不会对每个子表达式的“基础类型”感到困惑。您做错的地方是在操作之前添加对基础类型的强制转换,这没有什么好处。您需要在每次操作之后执行此操作。

+ 操作需要在 + 操作之后显式转换为基础类型,与 & 操作和移位操作相同。仅在最后将所有内容转换为基础类型是不够的,您必须单独考虑每个子表达式。

解释上面的代码:

第一行显式转换为 uint32_t,以确保 intNumber1U 的类型相同。这样,子表达式 intNumber + 1U 就不会发生隐式转换,并且这是与基础类型 uint8_t 具有相同符号性的更广泛类型(意味着它是安全的)。加法的结果是 unsigned int 类型。同样,unsigned int 和 unsigned int 不会产生隐式转换。最后将结果转换为 uint8_t 以满足许多 MISRA 规则。其余代码以同样的方式进行。

我总是尝试在操作之前对大整数类型进行扩展转换,以简化一切,避免隐式升级并避免彼此之间的大量转换。

请注意,规则 10.1 的真正目的是实际上迫使您了解 C 中的隐式类型提升。这是一个相当复杂的主题,但数量惊人的 C 程序员忽视了类型提升以及所有危险和风险。由它们引起的错误。 More info about the type promotion rules here .

关于c - 为什么 MISRA-C :2004 throw an error here?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27778975/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com