有没有充分的理由检查与布尔斯的平等性?

Is there some good reason to check equality with bools?

提问人:endolith 提问时间:4/17/2021 最后编辑:endolith 更新时间:4/17/2021 访问量:174

问:

我修改了一些芯片制造商的示例代码,删除了一堆我认为是愚蠢的布尔比较,例如:

  • if(var == TRUE)if(var)
  • if(TRUE == var)if(var)
  • if(var != TRUE)if(!var)
  • if(FALSE == var)if(!var)
  • if(TRUE == var1 || TRUE == var2)if(var1 || var2)
  • if(func() != FALSE)if(func())
  • if(func() == TRUE)if(func())

哪里:

#define TRUE                                   1
#define FALSE                                  0

我认为这会使代码更具可读性,甚至可能允许编译器更好地优化,但编译后的代码大小增加了 118 字节。

我错过了什么吗?这些在逻辑上应该是等价的,对吧?

c 布尔 嵌入式 相等 8051

评论

0赞 Eugene Sh. 4/17/2021
只是一个风格的东西。请注意,和不是标准值。TRUEFALSEbool
4赞 Eugene Sh. 4/17/2021
然后显示最小的可重现示例
2赞 Eugene Sh. 4/17/2021
此外,如果您使用的是一些“自制软件”而不是标准软件,则这些将不等价: - 因为可能具有 和 以外的值,那么右侧为真,而左侧则不是。boolif(var == TRUE) → if(var)var01
1赞 Eugene Sh. 4/17/2021
以下是使用正确类型与以下方法时的一些比较: godbolt.org/z/Y5PGr8fY1 正如你所看到的,当使用时,所有的结构都是等效的。使用时不同boolintboolint
2赞 David Schwartz 4/17/2021
@endolith 为什么你认为与1比较比与零比较更容易?我预计情况恰恰相反——很可能有“与零比较”操作,而与一个比较可能会使用“与常量比较”操作,该操作需要将一个作为常量提供。

答:

3赞 Marcus Müller 4/17/2021 #1

啊,这是我头顶上的,但是:

8051 有一个以寄存器中的单个位为条件的跳转指令,并且 .如果你的编译器知道要检查哪个位,它就可以使用它。JBJNB

或者,您可以检查累加器中的值是否为 0 或不是 0、、。但要做到这一点,您可能需要先将值放在累加器上,这可能需要清除并移动到该值,从而增加开销。JZJNZ

如果你的编译器不是很老派,请使用内置但不是标准或类似的“伪类型”,你的编译器将尽可能聪明地工作(并且可能做你打算做的事情)。_Bool

评论

0赞 Clifford 4/17/2021
我不确定这如何回答这个问题;编译器很可能会为任一习语生成相同的代码。如果导致编译器生成最佳分支,这不是一种方法。问题在于编码风格是否有充分的理由。这并不能回答这个问题。
1赞 Clifford 4/17/2021 #2

这不仅没有必要,而且是一个坏主意。只有与 FALSE 进行比较是安全的,因为任何非零值都是隐式的,但将这样的值进行比较可能会失败。trueTRUE

你做对了。虽然您可能需要考虑维护。如果供应商更新此代码,您可能需要重新应用所有更改。通常,按原样使用第三方代码会更简单;没有这样的代码会确认您特定的本地编码标准或风格 - 可能以摩尔的方式,而不仅仅是这样。忍受它或不使用它;当然不要复制它。

在您自己的代码中,最好使用 stdbool.h 和 和 。但是您仍然应该避免显式测试,因为它是不必要的。booltruefalse

但是,我要避免的是隐式转换。因此,例如,非空指针测试应该是而不是常见的成语。“规则”是条件表达式应显式为布尔值。在您的情况下,如果是布尔值,则无需测试是否等于真/假。相反,如果不是布尔值,则应使用布尔表达式 / 进行测试。boolif( ptr != NULL)if( ptr )varvar0 == var0 != var

这些建议主要涉及代码质量、健壮性、清晰度和可维护性。我怀疑它会对任何合理的编译器中的代码生成产生任何影响。