【问题标题】:Ternary operator argument evaluation in CC中的三元运算符参数评估
【发布时间】:2019-07-23 10:16:32
【问题描述】:

我一直在使用一些代码来确保符合 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

【问题讨论】:

  • 您可以完全避免使用三元运算符,例如return 0 == (uint32Var & 0x80000000u);。 (我不知道这是否符合 MISRA(ble) 规则。)

标签: c logic bitwise-operators conditional-operator misra


【解决方案1】:

这是安全的。

您将比较无符号的 32 位:

(uint32Var & 0x80000000u)

unsigned int

0u

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

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


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

【讨论】:

    【解决方案2】:

    我认为问题在于第一个参数是无符号数据类型,而不是布尔值,这意味着下面的修复将起作用。 /--/

    这是一个正确的改变吗?

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

    不过,假设函数返回uint32_t,你也可以这样写:

    return (uint32_t) !(uint32Var & mask);
    

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

    等效且兼容 MISRA-C:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-03
      • 2016-04-14
      • 2016-04-12
      • 2017-03-27
      • 1970-01-01
      • 2016-04-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多