journalctl 源中的 Void 包装函数

Void wrapped function in journalctl source

最近在浏览journalctl的源码,发现了一段不太明白的代码。

我说的部分就在这里: https://github.com/systemd/systemd/blob/9e83569d8ff219730912ecac441843b9531b079c/src/shared/logs-show.c#L1056

他们似乎想避免这样的多重检查

r = sd_journal_add_match(...);
if (r < 0) {
    //some error
}

来自 ||一起输出。

这样做不是也可以吗:

r = sd_journal_add_match(...);
r |= sd_journal_add_match(...);
...

为什么要将输出包装在

(void) ( ... );

?

提前致谢。

首先,

r |= sd_journal_add_match(...);

不一样
(r = sd_journal_add_match(j, "_UID=0", 0)) ||
(r = sd_journal_add_match(j, m2, 0)) ||

|=运算符是一个按位或运算符和赋值运算符(与r = r | sd_()相同),其中||逻辑或运算符。执行所有 sd_jourcal_ 函数,直到其中一个 return 为非零值。然后 r 包含这些非零值。这称为short-circuit评估。

其次,如果您对使用函数不感兴趣,我想这与我们(应该)将函数的 return 值转换为 void 的原因相同。例如:

(void)printf("Hello World");

这表明您现在 printf() return 是一个值,但您没有检查它们。通常你应该总是检查 return 值:

if (printf("Hello World") < 0) {
    // do some error handling here
}

简单写

printf("Hello World");

默默地忽略 return 值,这是个坏主意。我想,那里有用于关键软件的工具(如 lint),可以检查这一点。

对于您提供的示例,|| 链的结果被转换为 void。没有转换,代码看起来很奇怪,因为计算了一个值,但没有赋值。类似这样

f() || g(); // better (void)(f() || g());