【发布时间】:2019-09-01 19:28:53
【问题描述】:
在 bash 中我们可以说:
(
set -e
function OnError { caller | { read line file; echo "in $file:$line" >&2; }; }
trap OnError ERR ## catch exception
echo hello ## step 1
false
echo "never come here"
)
# continue here
每个命令都返回退出代码。标志 -e 告诉 bash 检查每个结果,如果结果不为零则退出。
C++ 中的异常提供了类似的逻辑:
#include <iostream>
using namespace std;
void step1(){
cout<<"hello"<<endl;
}
void step2(){
throw std::runtime_error("step2 always fail");
}
void step3(){
cout<<"never come here"<<endl;
}
int main(){
try{
step1();
step2(); // throws
step3(); // never come here
}catch(...){
cerr<<"caught error"<<endl;
}
// continue here
}
这也是一样的。但是需要额外的操作来检测异常是从哪里引发的。
C++ 开发人员通常拒绝使用带有-fno-exceptions 的异常。并且代码看起来像 C - 需要检查每个操作的结果。
#include <iostream>
using namespace std;
int step1(){
cout<<"hello"<<endl;
return 0;
}
int step2(){
return -1;
}
int step3(){
cout<<"never come here"<<endl;
return 0;
}
#define CHECK(err,msg) \
if(err){ \
cerr<<"error in "<<msg<<endl; \
break; \
}
int main(){
while(0){
CHECK(step1(),"step1");
CHECK(step2(),"step2");
CHECK(step3(),"step3");
}
// continue here;
}
这看起来有点麻烦。但是这里我们可以直接跟踪file:line。
我想要没有例外的干净代码。喜欢:
#include <iostream>
using namespace std;
enum Result {SUCCESS,FAIL};
Result step1(){
cout<<"hello"<<endl;
return SUCCESS;
}
Result step2(){
return FAIL;
}
Result step3(){
cout<<"never come here"<<endl;
return SUCCESS;
}
int main(){
{
step1(); // success
step2(); // fail , interrupt execution and go out of scope
step3(); // never come here
}
// continue here
}
如何实现与 bash 中相同的行为,保持代码简洁干净,没有例外?
【问题讨论】:
-
您的例外有什么问题?无论您是否
trycatch,它都能满足您的需求。 -
Qt 不使用异常。他们有理由。人们也不会在嵌入式系统中使用异常。这是一场圣战。无论如何想象 -fno-exceptions 是某些团队/环境/项目中的约定。
-
有一个 boost 结果库和一组宏,可让您在调用失败时退出范围,但这需要您重写应用程序。 boost.org/doc/libs/1_71_0/libs/outcome/doc/html/tutorial/…