如果我有一个返回某种指针的函数,我会在错误时将返回值设置为NULL来检查错误.
char *foo(void) {
//If stuff doesn't go okay
return NULL;
}
char *bar = foo();
if(!bar) return 1;
Run Code Online (Sandbox Code Playgroud)
这很有效,因为我知道在这种情况下我永远不会想要返回NULL.
但是,有时候我会有返回整数的函数(在这种情况下,我从配置文件中读取int).但是,问题是现在无法检查返回的值是否有错误,因为任何值(包括0)都可能是真的.
一些解决方法:
这两个问题都是我有一组函数,它们都做同样的事情,但对于不同的类型,我想维护一个常规接口,以便它们可以以相同的方式使用.
是否有其他解决方案不涉及更改功能的接口?处理这种情况最常见的方法是什么?
选择解决方案
感谢您对此的所有想法和答案.
最后我决定,如果函数是为了返回某些数据,则只能通过error参数返回错误.否则,将直接返回错误.
我选择了这个根,因为通常我发现当返回更复杂的数据形式时,潜在错误的数量几乎总是大于1.这意味着使用NULL作为错误数据的唯一来源是不切实际的,因为它意味着没有确定错误实际是什么的方法.对于将数据作为int返回的函数,也不可能将多个不同的错误代码与有效数据区分开来.
当然,对于没有真正返回任何数据的函数,情况也是如此,在这种情况下,我可以自由地将返回值用作错误代码.
我也喜欢上述模式明确区分返回数据的函数和不返回数据的函数.
有一个可怕的全局变量解决方案 - 类似于errno
. 不建议。
您可以使用函数来检索上次调用集合中函数之一的错误条件 - 再次强调,不推荐。这不是线程安全的,并且您可能会在函数之间共享错误 - 而不是能够从您使用的函数中询问最后一个错误(尽管这可以通过适当的设计来修复)。
您可能决定所有函数都返回可测试的状态,并且该值通过指针参数返回。这使您可以在使用模式发生变化的情况下实现所有功能的一致性。你会一直这样写:
if ((rc = your_function(in1, in2, &out)) != 0)
...handle error...
else
...use returned value...
Run Code Online (Sandbox Code Playgroud)
这可能是最不令人讨厌的解决方案。
另一种主要选择是传递指向错误结构的指针或指向错误结构的指针,这很容易导致资源管理问题。如果错误结构是固定大小,则可以使其工作,从而解决资源管理问题。
Error_t err;
int result = your_function(in1, in2, &err);
if (err.code != 0)
...handle error...
else
...use returned value...
Run Code Online (Sandbox Code Playgroud)
您无法在调用函数的同一行中测试错误条件,有些人会认为这是一个麻烦。当您处于一系列操作的第三个“else if”子句中时,这一点最为重要 - 然后您必须引入新的嵌套级别,其中错误代码作为返回值不需要这样做。有利的是,错误结构中的信息可以比单个错误号更全面,这可能会导致更好的诊断。
您可以使用混合解决方案 - 错误返回代码加上错误参数来包含改进诊断的额外信息。不过,据我所知,它很少被选择。
归档时间: |
|
查看次数: |
7360 次 |
最近记录: |