有没有更好的方法来做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,D1n")); 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 有没有更好的方法可以构建我的功能,还是其他人也有这个问题? 还有一个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将裤子从任何其他方法打败,但这不是其中之一. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |