journalctl 源中的 Void 包装函数
Void wrapped function in journalctl source
最近在浏览journalctl的源码,发现了一段不太明白的代码。
他们似乎想避免这样的多重检查
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());
最近在浏览journalctl的源码,发现了一段不太明白的代码。
他们似乎想避免这样的多重检查
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());