【发布时间】:2011-08-06 08:21:18
【问题描述】:
我正在尝试通过编写一个简单的解析器/编译器来学习 C。到目前为止,这是一次非常有启发性的体验,但是由于我拥有 C# 的深厚背景,我在调整时遇到了一些问题 - 特别是在缺乏异常方面。
现在我已经阅读了Cleaner, more elegant, and harder to recognize 并且我同意那篇文章中的每一个字;在我的 C# 代码中,我尽可能避免抛出异常,但是现在我面临一个我无法抛出异常的世界,我的错误处理完全淹没了原本干净且易于阅读的内容我的代码逻辑。
目前,我正在编写代码,如果出现问题,它需要快速失败,而且它也可能深度嵌套 - 我已经确定了一种错误处理模式,即“Get”函数出错时返回 NULL,其他函数在失败时返回 -1。在这两种情况下,失败的函数都会调用NS_SetError(),因此调用函数需要做的就是清理并在失败时立即返回。
我的问题是我所拥有的if (Action() < 0) return -1; 语句的数量正在引起我的注意 - 它非常重复并且完全掩盖了底层逻辑。我最终为自己创建了一个简单的宏来尝试改善这种情况,例如:
#define NOT_ERROR(X) if ((X) < 0) return -1
int NS_Expression(void)
{
NOT_ERROR(NS_Term());
NOT_ERROR(Emit("MOVE D0, D1\n"));
if (strcmp(current->str, "+") == 0)
{
NOT_ERROR(NS_Add());
}
else if (strcmp(current->str, "-") == 0)
{
NOT_ERROR(NS_Subtract());
}
else
{
NS_SetError("Expected: operator");
return -1;
}
return 0;
}
NS_Term、NS_Add 和 NS_Subtract 中的每一个函数都会执行 NS_SetError() 并在出错的情况下返回 -1 - 它的 更好,但它仍然感觉像我在滥用宏并且不允许进行任何清理(某些函数,特别是返回指针的 Get 函数更复杂,需要运行清理代码)。
总的来说,感觉就像我错过了一些东西 - 尽管以这种方式处理错误据说更容易识别,但在我的许多函数中,我真的很难确定错误是否得到正确处理:
- 某些函数在出错时返回
NULL - 某些函数在出错时返回
< 0 - 某些函数永远不会产生错误
- 我的函数执行
NS_SetError(),但许多其他函数没有。
有没有更好的方法来构建我的函数,或者其他人也有这个问题?
还有 Get 函数(返回指向对象的指针)在错误时返回 NULL 是个好主意,还是只是混淆了我的错误处理?
【问题讨论】:
-
我曾经认为在失败时返回 NULL 是个好主意,直到最近我处理一些继承代码时,函数可能由于各种原因返回 NULL。调试空指针并不好玩:)
-
滥用宏?你从未见过真正的宏滥用,儿子。
-
@zneak 我看到的宏导致了对宏的恐惧,因此我非常希望避免使用它们! :-)
-
@Skurmedel 引导我返回
NULL的原因是 SDL。这似乎是一个简洁的模式,因为这意味着您不需要单独测试NULL的 out 指针。
标签: c error-handling