微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

有没有更好的方法来做C风格的错误处理?

我正在通过编写一个简单的解析器/编译器来学习C.到目前为止,它是一个非常有启发性的经验,不过来自C#的强大背景我正在调整一些问题 – 特别是缺乏例外.

现在我已经读了Cleaner,more elegant,and harder to recognize,我同意那篇文章中的每一个字;在我的C#代码中,我尽可能地避免抛出异常,但是现在我遇到了一个我无法抛出异常的世界,我的错误处理完全颠覆了我的代码的干净和易于阅读的逻辑.

目前,我正在编写需要快速失败的代码,如果有问题,并且还可能深入嵌套 – 我已经解决一个错误处理模式,“Get”函数错误上返回NULL,其他函数返回-1失败.在这两种情况下,失败的函数调用NS_SetError(),所以所有调用函数要做的是清理并立即返回失败.

我的问题是if(Action()< 0)的数字返回-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,但它仍然感觉像我滥用宏,不允许任何清理(某些功能,特别是获取返回指针的函数,更复杂,需要清理代码才能运行).

总的来说,它只是觉得我失去了一些东西 – 尽管事实上,这种错误处理方式据说更容易识别,在我的很多功能中,我真的很难确定是否正确处理错误

>某些函数错误上返回NULL
>一些函数返回< 0出错
>某些功能不会产生错误
>我的函数一个NS_SetError(),但是很多其他函数都没有.

有没有更好的方法可以构建我的功能,还是其他人也有这个问题?

还有一个Get函数(返回一个对象的指针)返回一个错误的NULL一个好主意,还是只是混淆我的错误处理?

解决方法

一种用于清理的技术是使用永远不会实际迭代的while循环.它让你goto不使用goto.
#define NOT_ERROR(x) if ((x) < 0) break;
#define NOT_NULL(x) if ((x) == NULL) break;

// Initialise things that may need to be cleaned up here.
char* somePtr = NULL;

do
{
    NOT_NULL(somePtr = malloc(1024));
    NOT_ERROR(something(somePtr));
    NOT_ERROR(somethingElse(somePtr));
    // etc

    // if you get here everything's ok.
    return somePtr;
}
while (0);

// Something went wrong so clean-up.
free(somePtr);
return NULL;

你失去一定程度的缩进.

编辑:我想补充一点,我没有反对goto,只是对于问题的用例,他并不需要它.有些情况下,使用goto将裤子从任何其他方法打败,但这不是其中之一.

原文地址:https://www.jb51.cc/c/115537.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐