使用| =而不是=的具体原因

时间:2015-11-21 22:57:02

标签: c linux arm

我目前正在查看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体系结构上运行,因此可能必须对该平台的特定优化执行某些操作。

2 个答案:

答案 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中的=。提交评论指出:

  

避免在错误值上混淆| =。