不久前,我改变了处理 c 风格错误的方式。
我发现我的很多代码都是这样的:
int errorCode = 0;
errorCode = doSomething();
if (errorCode == 0)
{
errorCode = doSomethingElse();
}
...
if (errorCode == 0)
{
errorCode = doSomethingElseNew();
}
但最近我一直这样写:
int errorCode = 0;
do
{
if (doSomething() != 0) break;
if (doSomethingElse() != 0) break;
...
if (doSomethingElseNew() != 0) break;
} while(false);
我见过很多代码在出现错误后什么都不执行,但它总是以第一种风格编写。还有其他人使用这种风格吗?如果没有,为什么?
Edit:只是为了澄清,通常这个结构使用errno
否则我会将值分配给int
在打破之前。此外,通常还有更多的代码,而不仅仅是一个函数调用if (error == 0 )
条款。不过,有很多值得思考的好点。
如果您使用 C++,只需使用异常。如果您使用 C,第一种样式效果很好。但如果您确实想要第二种样式,只需使用 goto - 这正是 goto 真正是最清晰的构造的情况类型。
int errorCode = 0;
if ((errorCode = doSomething()) != 0) goto errorHandler;
if ((errorCode = doSomethingElse()) != 0) goto errorHandler;
...
if ((errorCode = doSomethingElseNew()) != 0) goto errorHandler;
return;
errorHandler:
// handle error
是的,goto 可能很糟糕,而异常或每次调用后的显式错误处理可能会更好,但 goto 比选择另一个构造来尝试和模拟它们要好得多。使用 goto 还可以轻松地为特定错误添加另一个错误处理程序:
int errorCode = 0;
if ((errorCode = doSomething()) != 0) goto errorHandler;
if ((errorCode = doSomethingElse()) != 0) goto errorHandler;
...
if ((errorCode = doSomethingElseNew()) != 0) goto errorHandlerSomethingElseNew;
return;
errorHandler:
// handle error
return;
errorHandlerSomethingElseNew:
// handle error
return;
或者,如果错误处理更多的是“展开/清理你所做的事情”,你可以这样构造它:
int errorCode = 0;
if ((errorCode = doSomething()) != 0) goto errorHandler;
if ((errorCode = doSomethingElse()) != 0) goto errorHandler1;
...
if ((errorCode = doSomethingElseNew()) != 0) goto errorHandler2;
errorHandler2:
// clean up after doSomethingElseNew
errorHandler1:
// clean up after doSomethingElse
errorHandler:
// clean up after doSomething
return errorCode;
这种习惯用法的优点是不重复清理代码(当然,如果您使用 C++,RAII 将更干净地覆盖清理代码。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)