使用if(!!(expr))而不是if(expr)

Moh*_*een 66 c expression

在阅读德州仪器为其SensorTag提供的示例代码时,我遇到了以下片段.

void SensorTagIO_processCharChangeEvt(uint8_t paramID) { 
    ...

    if (!!(ioValue & IO_DATA_LED1)) {
        PIN_setOutputValue(hGpioPin, Board_LED1, Board_LED_ON);
    } else {
        PIN_setOutputValue(hGpioPin, Board_LED1, Board_LED_OFF);
    }

    if (!!(ioValue & IO_DATA_LED2)) {
        PIN_setOutputValue(hGpioPin, Board_LED2, Board_LED_ON);
    } else {
        PIN_setOutputValue(hGpioPin, Board_LED2, Board_LED_OFF);
    }

    if (!!((ioValue & IO_DATA_BUZZER))) {
        Clock_start(buzzClockHandle);
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

声明就像这样(在同一个文件中).

#define IO_DATA_LED1   0x01
static uint8_t ioValue;
Run Code Online (Sandbox Code Playgroud)

是否if (!!(ioValue & IO_DATA_LED1))提供任何优势if (ioValue & IO_DATA_LED1)

fuz*_*fuz 79

!两次应用逻辑not()运算符的目的是将值规范化为0或1.在if语句的控制表达式中,这没有任何区别.if语句只关心值为零或非零,小!!舞蹈完全没用.

一些编码风格指南可能要求这种舞蹈,这可能是您发布的TI代码的原因.虽然我没有看到任何这样做.

  • 同意.在嵌入式编程中也很常见.我怀疑这是展开的一些遗物,例如一个'BITTEST`宏,它应该返回一点的值,而不仅仅是用于进一步处理的设置/清除信息.不是这样的代码通常是由学生等编写的,这些学生本身并不是很有经验(并且报酬不高),所以他们倾向于使用现有的模式而不能很好地优化/增强. (8认同)
  • @Olaf由于Java是一种强类型语言,因此除了可以应用逻辑否定的布尔值之外,没有其他操作数类型,使得双重否定无用.我能想到的唯一可能的原因可能是在应用于盒装布尔时强制使用NPE. (7认同)
  • @ GOTO0:哪个**可能**让他们成为经验丰富的Java devs_,但不是_经验的C devs_. (5认同)
  • 一些编译器警告像if(a = b)`这样的结构,因为它们可能是错误的.你可以用`if((a = b)!= 0)`来避免警告,但这就像罪一样难看.`if(!!(a = b))`有点*更简洁. (3认同)
  • @EOF通常,编译器会选择`if((a = b))`.我认为这个惯例可以追溯到lint. (3认同)

Dam*_*ick 54

表达式!!x,或者!(!x),表示1 if x是真值(非零数字或非空指针),否则为0.它相当于x != 0,它与C99几乎相同(_Bool)x但在C99之前的编译器中可用,或者其开发人员未选择实现C99(例如针对MOS 6502的cc65).

有条件的整体相当于以下内容:

if (ioValue & IO_DATA_LED1) {
    /* what to do if the IO_DATA_LED1 bit is true */
} else {
    /* what to do if the IO_DATA_LED1 bit is false */
}
Run Code Online (Sandbox Code Playgroud)

在C中,它表示"如果这两个值的按位AND非零,则执行该块."

但是一些编码样式指南可能会禁止&if语句条件的顶层使用按位AND(),假设它是逻辑AND(&&)的拼写错误.它与使用=(赋值)而不是==(相等比较)处于同一类错误中,许多编译器为此提供诊断.GCC警告选项描述了以下诊断:

-Wlogical-op:警告表达式中可疑的逻辑运算符使用.这包括在可能期望按位运算符的上下文中使用逻辑运算符.

-Wparentheses:如果在某些上下文中省略括号,则发出警告,例如在预期真值的上下文中存在赋值时

意译的用途,例如(a & B) != 0,(_Bool)(a & B)!!(a & B)编译器和其他开发人员使用位运算符的是故意的通信.

另请参阅!!xJavaScript中的相关答案.

  • 这是一个比接受的答案更好的答案,它没有解决按位运算符问题. (5认同)

Yak*_*ont 16

在MSVC中,boolif语句中隐式转换整数可以生成警告.通过这样做!!没有.其他编译器中可能存在类似的警告.

因此,假设代码是在启用该警告的情况下编译的,并且决定将所有警告视为错误,使用!!是一种简单且可移植的方式来表示"是的,我希望此整数为bool".