C API应该返回值还是错误码?

9

我正在编写我的第一个C语言库,但不确定该如何进行。例如,从某个数据存储中检索字符串值的函数可以如下所示:

int get_value(void * store, char ** result);

或者

char * get_value(void * store, int * error);

我很难找到一个客观的理由来偏爱其中之一,但是我不经常写C语言。当多个输出参数存在时,返回错误代码看起来更加一致,但是返回值可能更容易使用?不确定。

是否有关于哪种风格更好的普遍共识以及为什么,还是只是个人喜好?


1
这完全是基于个人意见的,但我更喜欢第一个。不过,我会将其更改为 int get_value(void * store, char * result, int max_len); 这样调用者就可以分配内存,而内存所有权不会来回转移。 - mnistic
这是个人偏好问题,根据我的经验,第一种形式似乎更为普遍。通常负整数表示错误,非负整数表示成功。有些人使用0表示失败,1表示成功,但最好与_Bool相关联。Pthread和fam使用0表示成功,非0(通常为正数)表示错误代码。 - Petr Skocik
1
普遍的共识是按照你的同事们的方式去做。 - jxh
相关内容:https://dev59.com/-XRC5IYBdhLWcg3wK92V - AShelly
@AShelly 绝对相关,谢谢 :) - graywolf
1个回答

12

这类基于风格的问题通常没有“硬”答案。以下是我的观点;其他人可能会有不同看法。

  • 让一个函数仅返回其返回值通常会使调用者更容易使用,前提是调用者对获取答案感兴趣,而不一定是最佳错误处理。

  • 所有函数都返回成功/失败代码,通过“结果”参数返回任何其他数据,可以实现清晰且一致的错误处理,但往往不方便调用者。您总是需要声明额外的变量(正确类型的变量)来保存返回值。您可能无法编写像a = f(g());这样的代码。

  • 通常使用返回普通值,并通过“out of band”普通返回值指示错误 - 典型的例子是标准C库中的getchar函数,但这种方法可能感觉相当杂乱和容易出错。

  • 通过返回值返回值,通过“返回”参数返回错误代码是不寻常的。我能看到它的吸引力,但我从未使用过这种技术,也不会使用。如果需要与返回值不同的错误返回,那么“C方式”(虽然这通常是一个非常糟糕的想法,并且现在已经被强烈禁止使用)是使用某种类似于errno的全局变量。

  • 如果你想要遵循C语言原始的“便利精神”,那么不必担心过于严格一致性,也不必刻意保持一致性和特定性。因此使用带外错误返回是可以的。

  • 如果你想要遵循现代用法,越来越倾向于一致性和正确性,这意味着即使它们不太方便,一致的错误返回方案也是好的。因此,将返回值设置为成功/失败代码,并通过结果参数返回数据是可以的。

  • 如果你想让返回值作为返回值,以方便使用,并且错误很少发生,但对于关心错误信息的调用者,你想给他们一种获取细粒度错误信息的方法,一个好的折衷方案有时是有一个单独的函数来获取最近错误的详细信息。这仍然可能导致与全局变量相同类型的竞争条件,但如果您的库使用某种“描述符”或“句柄”,以便您可以安排该错误详细信息函数返回在特定句柄上的最近操作的详细信息,它可以工作得很好。


  • 网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接