可能重复:
Error handling in C code
大家好。我正在使用C进行一些小项目,我知道如何,因为它没有专门的错误处理结构,我必须用额外的条件块污染我的算法。我的问题是你更喜欢如何处理错误,并说明原因。我在两种方式之间挣扎......如果你有第三种方式,发布它。感谢。
///////////////////////////////////////////
// method 1
// stuff that can go wrong;
if (test1 == failed)
{
// print error;
// exit;
}
else
{
// more stuff that can go wrong;
if (test2 == failed)
{
// print error;
// exit;
}
else
{
// ... and so on...
}
}
///////////////////////////////////////////
// method 2
// stuff that can go wrong;
if (test1 == failed)
{
// print error;
// exit;
}
// more stuff that can go wrong;
if (test2 == failed)
{
// print error;
// exit;
}
// ... and so on...
答案 0 :(得分:5)
有些人不同意我这个,但我使用goto的。在每个函数内部,最后我在结尾处有一个块,看起来像这样
if (0)
{
ERROR:
// Handle errors, and exit/return after potentially freeing resources
}
然后我使用if (something_bad) goto ERROR;
没有其他东西。
许多人不喜欢goto,但这是实现此目的而不是复制代码的方法。如果你真的坚持不使用goto,我会这样做:
#define LOCAL_ASSERT(COND) if (COND) { \
/* Handle errors, and exit/return after potentially freeing resources */ \
}
在每个函数的开头添加一个定义,然后在函数末尾添加#undef LOCAL_ASSERT
。这允许在每个函数处进行不同的错误处理,而不会用不同的宏名称污染整个程序。
然后我只是在任何地方使用LOCAL_ASSERT(cond)
。
编辑:让自己更清楚,这是多次保存写错误处理代码。如果您想要小型自定义,则可以轻松设置错误变量字符串(或将其添加为宏参数)。我根本不喜欢别的东西。我通常做
// method 1
if (error) goto ERROR; // no else
// method 2
LOCAL_ASSERT(cond);
Elses会污染您的代码并需要更多缩进,这有时很烦人。
答案 1 :(得分:1)
我在某种程度上知道它的用户偏好,但我很难从每个函数或最多两个退出点建立单个出口点(但它们必须明显且容易断点) :
const Bool funcFoo(int someval, int someval2, int someval3)
{
if(someval == okval)
{ // We're ok
if(someval2 == okval2)
{ // Still ok.
if(someval3 == okval3)
{ // Yippee! We made it!
return True; // <===== ONLY SUCCESS RETURN POINT
}
}
}
// Houston, we had a problem.
return False; // <===== ONLY FAIL RETURN POINT
}
在“else
”很重要的情况下,它是类似的展开,但我们只保留两个返回点:
const Bool funcFoo(int someval, int someval2, int someval3)
{
if(someval == okval)
{ // We're ok
if(someval2 == okval2)
{ // Still ok.
if(someval3 == okval3)
{ // Yippee! We made it!
return True; // <===== ONLY SUCCESS RETURN POINT
}
else
{ // someval3 is bad.
//...maybe handle, not return.
}
}
else
{ // someval2 is bad.
// ...maybe handle, not return.
}
}
else
{ // someval is bad.
// ...maybe handle, not return.
}
// Houston, we had a problem.
return False; // <===== ONLY FAIL RETURN POINT
}
有几件事需要提及:
else
”代表
仅用于调试目的,在此处
我将它们包裹在#ifdef _DEBUG ... #endif
答案 2 :(得分:0)
我宁愿使用这样的东西:
if (test1 == failed)
{
// print error;
// exit;
}
else if (test2 == failed)
{
// print error;
// exit;
}
else
{
// ... and so on...
}
它更具可读性,它限制了缩进。它还清楚地告诉我,如果一个条件失败,它将尝试所有其他条件,直到它最终失败;没有机会同时满足2个条件。
答案 3 :(得分:0)
我投票支持方法2.正如您所提到的,方法1中的错误处理模糊了“真实”算法的逻辑。