今天在工作中我们讨论了这个话题,但是没有人能够给出一个明确的答案。请考虑以下情况:
int foo()
{
int err;
err = some_call(1);
if (err != 0)
return err;
err = some_call(2);
if (err != 0)
return err;
err = some_call(3);
if (err != 0)
return err;
err = some_call(4);
if (err != 0)
return err;
bar();
return err;
}
有很多代码重复。显然,这可以通过宏进行因式分解,但很遗憾不能用模板(因为有返回条款)。或者至少不是直接的。
现在的问题是,如果我们用异常替换那些返回错误代码,并立即捕获这些异常,编译器是否允许并聪明到足以检测该模式并完全避免抛出异常?
这里是我的意思的说明:
int foo()
{
try
{
// some_call now throws a ErrorReturned exception that contains the error code upon failure.
some_call(1);
some_call(2);
some_call(3);
some_call(4);
}
catch (ErrorReturned& ex)
{
return ex.error_code();
}
bar();
return 0;
}
现在,没有当前的性能问题,所以是的,我们不需要优化甚至关心它。这更多是为了理解编译器可以做什么。
简而言之,这是一种“好”的做法吗?如果是,编译器是否可以通过根本不抛出异常来进行优化?(假设异常构造没有副作用)
if ((err = some_call(1))) return err;
怎么样? - NPEsome_call
被内联,那么编译器可以用实际上的goto替换throw/catch。至于你的编译器是否这样做,没有什么比盯着(反)汇编更好的替代方法了 :-) 快速查看一下,使用-O3的gcc 4.8.1,在一个带有throw/catch的函数中,生成的代码仍然会分配异常对象并进行解旋。 - Steve Jessop