我目前在审查 Linux 内核中的一些代码(热管理)。在某些地方,返回值用于发出错误信号,在函数开始时将其设置为 0。然后,调用可能失败的函数时,使用|=
而不是=
来将其设置为新值。以下是一个例子:
int ti_bandgap_read_temperature(struct ti_bandgap *bgp, int id,
int *temperature)
{
u32 temp;
int ret;
ret = ti_bandgap_validate(bgp, id);
if (ret)
return ret;
spin_lock(&bgp->lock);
temp = ti_bandgap_read_temp(bgp, id);
spin_unlock(&bgp->lock);
ret |= ti_bandgap_adc_to_mcelsius(bgp, temp, &temp);
if (ret)
return -EIO;
*temperature = temp;
return 0;
}
ti_bandgap_validate
的定义如下:/**
* ti_bandgap_validate() - helper to check the sanity of a struct ti_bandgap
* @bgp: struct ti_bandgap pointer
* @id: bandgap sensor id
*
* Checks if the bandgap pointer is valid and if the sensor id is also
* applicable.
*
* Return: 0 if no errors, -EINVAL for invalid @bgp pointer or -ERANGE if
* @id cannot index @bgp sensors.
*/
static inline int ti_bandgap_validate(struct ti_bandgap *bgp, int id)
因此,如果我的推理正确,在调用
ti_bandgap_adc_to_mcelsius()
时,ret
的值必须为 0
(否则该函数已经退出)。那么在这里使用 |=
而不是 =
的原因是什么呢?使用一个全零模式进行“或”运算将只返回正常模式。这是某种针对通常情况的优化吗,即函数没有返回失败(即返回值为 0
)?还是我漏掉了其他差异?此代码在 ARM 架构上运行,因此可能与该平台的特定优化有关。
E...
错误常量进行 OR 运算,这是没有意义的。保留一个毫无意义的非零值并不比完全丢失它更好。其次,从具体的角度来看,它强制代码的读者四处搜索并手动推断出ret
在那一点上保证为零,从而使|=
等同于=
。强迫读者做出这样不必要的努力从来都不是一个好的形式。 - AnT stands with Russia