在journalctl源中无效包装函数

时间:2016-02-08 11:09:16

标签: c call void

我最近浏览了journalctl的源代码,发现了一段对我来说不太清楚的代码。

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

似乎他们想要像这样的多次检查

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

by ||产出在一起。

这样做也不可能:

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

为什么将输出包装在

(void) ( ... );

提前谢谢。

1 个答案:

答案 0 :(得分:0)

首先,

r |= sd_journal_add_match(...);

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

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

其次,我想这就是为什么我们(应该)将函数的返回值强制转换为void的原因,如果你不想使用它们的话。例如:

(void)printf("Hello World");

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

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

简单写作

printf("Hello World");

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

对于您提供的示例,||链的结果已投放到void。没有强制转换,代码看起来很奇怪,因为有一个值已计算但未分配。类似这样

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