gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 11:48:50 25 4
gpt4 key购买 nike

我目前正在查看 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 架构上运行,因此它可能必须针对该平台进行特定优化。

最佳答案

在这种情况下,没有理由使用 |=但是,如果您正在跟踪许多可能出错的函数,并且如果它们出错则作为返回码返回,则模式是

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);

对于大多数项目来说,返回多个错误并将它们作为一个错误来处理并不是很明智;但有时在错误抑制很重要时会这样做。例如,如果您无法将消息从客户端传输到主机,您可能会抑制各种“无法打开套接字”、“无法写入套接字”、“无法复制到缓冲区”等失败。变成通用的“发送 X 失败”。在一个层面上,整个顶层工作流失败了,如果需要,原因的详细信息仍然在一定程度上可用。

关于c - 使用 |= 而不是 = 的具体原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33849606/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com