我正在寻找一种健壮的方式来报告C库中的错误。考虑一个简单的队列示例:
struct queue *q = malloc(sizeof(*q));
if (NULL == q) {
/* malloc failed. now what ? */
return NULL; /* maybe ? */
}
好的,对于这个例子,返回NULL
是无效的,所以返回它来表示一个错误是有意义的。但
void *get_data()
{
/* stuff */
/* Error detected. NULL is a valid return, now what ? */
/* stuff */
}
更重要的是,一旦我们发出错误信号,如何发出错误信号?我已经考虑过了,但没有一个令人满意的解决方案。
使用errno
或其他全局对象的
errno
相当难看。那么你对这个主题有什么看法?如何以干净的方式报告错误?
发布于 2011-07-01 23:14:19
int get_data(void **ptr)
如果没有明显的“错误返回”,那么也许你的输出值不应该是返回值。错误可以是errno、其他自定义的详细错误值(*cough* HRESULT)、函数成功与否的true/false或其他一些有用的信息(数据长度,如果出错,则为-1 )
发布于 2011-07-01 21:56:59
我有几个建议。
建议#1 --使用自定义的errnos。我知道您表示不愿使用它。我知道您担心errno会在多线程环境中受到破坏,但我希望每个线程都有自己的errno存储空间。下面的链接http://compute.cnr.berkeley.edu/cgi-bin/man-cgi?errno+3表明这很容易做到。
至于定制errno的结构,您总是可以将errno分成两部分……模块号和模块错误代码。
eg.
#define MODULE_NAME_error_code ((MODULE_NUMBER << 16) | (error_code))
如果在库中检测到错误,则可以将errno设置为所需的值。如果有多个模块,它可以帮助识别问题区域。当然,如果您的库要与使用此方法的其他库一起使用,则需要对自定义errno进行某种形式的同步。
建议#2 --让您的例程在成功时返回0,并在返回时返回一个自定义的非零值,并让其中一个参数成为您想要设置的值的指针。可以很容易地检测到错误;但是,如果您有使用这种方法的深层调用树,则记录这些错误可能会很麻烦。
希望这能有所帮助。
发布于 2011-07-01 21:49:29
如果你真的想要一种多线程、可重入的方式来报告错误,我认为你不能在每次lib调用中都传递一个指向"status“结构的指针。除了其他对象状态内容之外,该结构还会包含有问题的调用结果。
它确实很难看,但不一定不好。
https://stackoverflow.com/questions/6548749
复制相似问题