我目前正在查看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体系结构上运行,因此可能必须对该平台的特定优化执行某些操作。
答案 0 :(得分:3)
在这种情况下,没有理由使用|=
但是,如果您正在跟踪可能出错的多个函数,并且如果它们作为返回代码出错则返回,则模式为
boolean error = false
error |= doFirstStep(...);
error |= doSecondStep(...);
error |= doThirdStep(...);
if (error) {
printf("error occurred: %s\n", strerror(errno));
}
它是C中较少使用的模式,偶尔用于与C有一定关系的语言。在C语言中,大量的C库函数返回错误代码"成功操作时通常为0。
使用此模式时,用户依赖于返回零作为成功条件。这意味着上述log_and_recover()
可能会将错误消息从error.h中拉出一个静态变量,这与C #include <error.h>
例程相同。
----继续为什么这经常用在int字段----
你也会看到这个模式,int
持有错误。
int error = 0; // or a variable that's defined to zero
error |= doFirstStep(...);
error |= doSecondStep(...);
error |= doThirdStep(...);
if (error != 0) {
... some error handling ...
}
当你看到这个时,它与上面的想法相同,但开发人员结合了两种模式。通常用于打包配置参数的位字段模式被用于打包多种错误。通常,当发生这种情况时,您可以找到类似于
的错误列表#define ERROR_NO_DISK (1<<1);
#define ERROR_NO_NETWORK (1<<2);
#define ERROR_NO_SANITY (1<<3);
对于大多数项目来说,返回多个错误并将其作为一个整体处理是不是非常敏感;但有时在错误抑制很重要时就完成了。例如,如果您无法将消息从客户端传输到主机,则很可能会抑制各种打开套接字的失败&#34;,&#34;无法写入套接字&#34;,& #34;无法复制到缓冲区&#34;等失败到通用&#34;无法发送X&#34;。在一个层面上,整个顶级工作流程都失败了,如果需要,还可以获得有关原因的详细信息。
答案 1 :(得分:2)
在此上下文中没有理由使用|=
。正如您所说,当达到此行时,ret
必须为0,否则它将在之前返回。它还引入了一个不必要的附加操作。
正如评论中所提到的,此运算符实际上已更改为this commit中的=
。提交评论指出:
避免在错误值上混淆| =。