【发布时间】:2016-11-05 14:47:45
【问题描述】:
假设一个 API,其中每个函数都返回一个错误代码,在没有错误的情况下为零,在错误值的情况下为非零。
让
int foo(...);
int bar(...);
成为此 API 中的函数。假设有一个代码片段,其中必须按顺序调用foo 和bar 并且应该始终调用 foo 和 bar,而不管先前的错误,但是传播第一个返回的非零错误码,即
int foobar(...)
{
int rc = 0, rc_;
/* ... */
rc_ = foo(...); rc = rc ? rc : rc_;
rc_ = bar(...); rc = rc ? rc : rc_;
return rc;
}
编写 rc,rc_ 多路复用很累并且容易出错(无论是否使用三元运算符、if/else 或其他东西)。
让传播辅助函数出现错误
static inline
int rc_propagate(int r, int p){ return p ? p : r; }
这可以像这样在foobar中使用
int foobar(...)
{
int rc = 0;
/* ... */
rc = rc_propagate(foo(...), rc);
rc = rc_propagate(bar(...), rc);
return rc;
}
C 标准是否允许通过将 rc_propagate 的第一个参数(一个静态内联函数)的评估拉到三元中进行优化,这样如果第二个参数 @ 时,由于三元运算符评估规则,它可能不会被执行987654329@ 非零?
【问题讨论】:
-
我认为没有,但我会等待有人引用标准的相关部分。
-
@2501:只是在这种情况下它不是外部函数,而是静态内联。我的怀疑完全是关于静态内联;具体来说,我刚刚阅读了 LLVM 开发人员的一些博客文章以及关于调用静态内联函数的可能优化。
-
顺便说一句,您为什么不直接写:
rc = rc ? rc : foo(...);并完全避免这个问题? -
我认为因为对
bar()的函数调用是内联函数的参数,所以即使foo()失败也必须调用它——这不是你想要的。无论rc_propagate()函数是否内联,程序的行为都不应改变。 -
如果您想要无论如何都要对其进行评估,我认为内联函数会做到这一点。如果没有,您可以尝试类似函数的宏...
标签: c optimization language-lawyer