C 中的三元运算符参数评估

Ternary operator argument evaluation in C

我一直在使用一些代码来确保 MISRA 合规性。这段代码的问题是

Operands shall not be of an inappropriate essential type. The operand of the ? operator is of an inappropriate essential type category unsigned. 

我假设问题出在第一个参数是无符号数据类型,而不是布尔值,这意味着下面的修复会起作用。

原创,

 return (uint32Var & 0x80000000u) ? 0u : 1u;

我对代码的修改,

 return ( (uint32Var & 0x80000000u)!=0u ) ? 0u : 1u;

这是一个正确的改变吗?我担心更改代码的功能,但据我所知,至少在 if 逻辑中,操作数在 if ( numVar ) 运算符内被评估为 numVar != 0

那是安全的。

您将比较无符号的 32 位:

(uint32Var & 0x80000000u)

unsigned int:

0u

Usual arithmetic conversions 适用于确保无论此处涉及的实际类型如何,您将比较至少足以包含无符号 32 位的类型的值。

(uint32Var & 0x80000000u)如果等于0则为假,否则为真。将值与 0 进行比较会产生效果,如果比较相等则产生 0,否则产生 1 是等效行为。


另外请注意,您最终为三元运算符的第一个操作数使用的值不是 bool,而是 int!= 运算符产生 01int 值。

I assume the issue is with the first argument being an unsigned data type, instead of boolean, which means the fix bellow would work. /--/

Is this a correct change to make?

是的。如前所述,它将使代码符合 MISRA 标准。警告确实是关于对第一个操作数使用非布尔类型。

但是,假设函数returns uint32_t,你不妨写成:

return (uint32_t) !(uint32Var & mask);

(mask 因为 MISRA 和其他人一样,不鼓励使用“幻数”。)

等效且与 MISRA-C 兼容:

return ~uint32Var >> bits; // where bits in this case is 31

通常,~ 运算符在编写 MISRA 兼容代码时是一个令人讨厌的部分,但是当您使用非小整数类型的无符号整数类型时,它是非常安全的,例如 uint32_t .