当"|"非常好时,为什么要使用"+"运算符?

Why use the '+' operator when '|' is perfectly good?

本文关键字:运算符 为什么 非常好      更新时间:2023-10-16

这更多的是一个哲学问题,但我在代码库中看到过很多次,并不真正理解这种编程方法是如何产生的。

假设您必须将位2和3设置为某个值x,而不更改uint中的其他值。这样做很琐碎,也是一项常见的任务,我倾向于这样做:

uint8_t someval = 0xFF; //some random previous value
uint8_t x = 0x2; //some random value to assign.
someval = (somval & ~0xC) | (x << 2); //Set the value to 0x2 for bits 2-3

我看到过使用"|"或使用"+"的代码:

uint8_t someval = 0xFF; //some random previous value
uint8_t x = 0x2; //some random value to assign.
someval = (somval & ~0xC) + (x << 2); //Set the value to 0x2 for bits 2-3

它们等效吗

一个比另一个好吗
只有当你的硬件没有位或指令时,但我从未见过没有位或的处理器(即使是小型PIC10处理器也有或指令)。

那么,为什么有些程序员会倾向于使用"+"而不是"|"呢?我是不是错过了一些非常明显、超级强大的优化?

  • 如果要执行按位运算,请使用按位运算符。

  • 如果要执行算术运算,请使用算术运算符。

的确,对于某些值,一些算术运算可以作为简单的逐位运算来实现,但这本质上是一个实现细节,您永远不应该向读者公开。首先,代码的逻辑应该是清晰的,如果可能的话,应该是不言自明的。编译器将为您选择适当的低级操作来实现您的愿望。

这就是慈善。

它们等效吗?

是的,只要要写入的位字段事先清除即可。否则,它们会以稍微不同的方式出错。

一个比另一个好吗?

不,尽管有些人会说比特操作更清楚地表达了意图。

那么,为什么有些程序员会倾向于使用"+"而不是"|"呢?

因为它们是等价的,两者都不是特别好。

我是不是错过了一些非常明显、超级强大的优化?

没有。

那么,为什么有些程序员会倾向于使用"+"而不是"|"呢?

+可以更快地发现逻辑错误。a | a似乎可以工作,而简单的a + a肯定不会(当然,这取决于逻辑,但+版本更容易出错)。

当然,你应该坚持标准的做事方式(当你想要按位运算时使用按位运算,当你想要做数学运算时使用算术运算)。

这只是一个风格问题。任何现代CPU都将在相同的周期数(通常为1)内完成这两个操作。就我个人而言,在这种情况下,我更喜欢|,因为它更明确地向代码读取器表明,你在做比特处理,而不是算术。

如果你的代码中有一个bug,那么使用+可能会导致奇怪的行为,而使用|则会掩盖这个bug。例如,如果您意外地包含同一位两次,则再次对其进行"或"运算是不可行的,但添加它将清除该位并进位到下一位(如果设置了更多位,则可能更远)。因此,这通常会导致快速故障行为,而不是通常更可取的故障屏蔽行为。