2010-01-26 35 views
7

我的程序是用C编写的Linux,并有不同的图案很多函数的返回值:失败成功在C中决定返回值的一般方法是什么?

1)一个或两个复位n-1
2)一些成功返回0-1失败。
3)一些成功返回1,失败时返回0(我通常使用布尔类型转义)。
4)指针返回0失败(我通常使用NULL转身)。

我产生了困惑比前三 - 函数返回的指针总是在失败时返回0,这很容易。

第一个选项通常涉及函数返回的长度可能只是积极的。

第二个选项,通常涉及命令行处理功能,但我不能确定它的正确性,也许更好的价值将是EXIT_SUCCESS和EXIT_FAILURE?

第三个选项是用于其是方便,自然要条件范围内调用的函数,并且我通常这里模拟布尔类型,通过使用int值1和0

尽管所有这似乎合理合理的,我仍然发现哪些地方对于创建函数时使用哪种风格或者希望使用哪种风格时不太清楚或明显。

所以在返回类型决定这里的时候,我怎么能增加清晰度我的做法?

+2

为什么你会使用NULL?或布尔类型,对于这个问题? – 2010-01-26 19:16:34

+4

'NULL'为0,除了'NULL'附加的语义信息比0多。 – 2010-01-26 19:30:05

+1

减少打字;-) – 2010-01-26 22:31:54

回答

4

所以在返回类型决定这里的时候,我怎么能增加清晰度我的做法?

挑选一个模式每返回类型并坚持下去,否则你会让自己疯狂。模型上早已建立了平台的约定你的模式:

  • 如果要进行大量的系统调用,比任何整数返回函数应该在失败时返回-1

  • 如果不进行系统调用,你可以自由地遵循非零空调控制结构的公约表示成功,零表示失败。 (我不知道你为什么不喜欢bool。)

  • 如果一个函数返回一个指针,失败应该返回NULL

  • 如果函数返回一个浮点数,故障应通过返回为NaN来指示。

  • 如果一个函数返回一个全方位的符号和无符号整数,你可能不应该编码的返回值是成功还是失败。

返回值的测试对C程序员来说是个麻烦。如果失败很罕见,并且您可以编写中央处理程序,请考虑使用可使用longjmp指示失败的exception macro package

2

一个条件,我能想到的地方你的上述方法可以失败是可以返回包括-1的任何值的功能,说一个函数将两个有符号数。

在这种情况下,测试-1肯定是一个坏主意。

如果出现问题,我最好设置一个由C标准提供的全局错误条件标志,格式为errno,并用它来处理错误。
虽然,C++标准库提供了异常,为错误处理带来了很大的难度。

0

所以在返回类型决定这里的时候,我怎么能增加清晰度我的做法?

只是,你正在考虑这一事实是一个很长的路要走。如果你想出一条或两条规则 - 或者如果它们有意义的话可能更多(你可能需要一条以上的规则 - 就像你提到的那样,你可能想要处理返回的指针与其他事物不同),我想你会变得更好比许多商店。

我个人喜欢有0返回信号故障和非零表示成功,但我没有强烈需要坚持这一点。我可以理解可能想要扭转这种感觉的哲学,以便您可以返回失败的不同原因。

最重要的是要有遵循的准则。更好的是制定具有书面理由的指导方针(我相信,有理由,人们更可能遵循指导原则)。就像我说的,只是你想到这些事情的事实让你领先于其他许多人。

3

不是一个实际的回答你的问题,但有些乱评,你可能会感兴趣:

  • 它通常明显,当使用情况(1),但是当无符号类型涉及它变得丑陋 - return (size_t)-1仍然有效,但它不漂亮

  • 如果您使用的是C99,则使用_Bool没有任何问题;海事组织,它不仅仅是使用int

  • 我用return NULL,而不是return 0在指针上下文(peronal偏好)清洁了很多,但我很少检查它,因为我觉得它更自然地只是把指针作为布尔;一个常见的情况是这样的:

    struct foo *foo = create_foo(); 
    if(!foo) /* handle error */; 
    
  • 我尽量避免的情况下(2);使用EXIT_SUCCESSEXIT_FAILURE可能是可行的,但IMO这种方法才有意义,如果有两个以上的可能的结果,你将不得不使用一个enum反正

  • 对于更复杂的程序,它可能是有意义的实现你的自己的错误处理方案;有使用setjmp()/longjmp()周围一些相当高级的实现,但我喜欢的东西errno样用不同的变量不同类型的错误

4

你为什么不使用C标准库使用的方法吗?哦,等等...

+0

也许是因为我不熟悉它,照顾开导我? – 2010-01-26 20:06:29

+0

蒂姆可能只是在讽刺一个事实,即C标准库在这一点上并不是真的一致... :-) – 2010-01-26 20:47:34

+0

啊我看到了,必须保持这个偏执狂... – 2010-01-26 22:07:40

2

对于不能确定性的失败。使用更具体的(bool)返回类型的是/否响应可以帮助保持一致性。进一步寻求更高层次的接口,人们可能想要考虑返回或更新系统特定的消息/结果细节结构。

我为0的偏好永远是一个成功是基于以下思路:

  1. 零使得由负VS正值举办故障,如完全失败VS条件成功一些基本的分级。我不推荐这样做,因为它往往太浅而不实用,可能导致危险的行为假设。

  2. 当成功是零人可以让一束正交的呼叫和通过比较组的返回代码检查在单个条件群组成功以后简单地..

    RC = 0; rc + = func1(); rc + = func2(); rc + = func3(); if(rc == 0) 成功!

  3. 最重要的是,从我的经验来看,零似乎是标准库和第三方系统工作成功的一致指示。

0

这是一个偏好问题,但我注意到的是不一致。考虑这种使用预C99编译

 
#define SUCCESS 1 
#define ERROR 0 

然后返回一个int任何函数,返回一个或另一个以减少混乱,并坚持下去宗教。再次,根据并考虑到开发团队,坚持他们的标准。

在预C99编译器,零一个int是假的,任何大于零的为真。这取决于你的编译器是什么标准,如果它是C99,则使用stdbool的_Bool类型。

C的一大优点是你可以使用你的个人风格,但是在需要团队努力的情况下,坚持团队的标准并且遵循它的宗旨,即使在你离开那个工作之后,另一个程序员也会感激你的。

并保持一致。

希望这会有所帮助, 最好的问候, 汤姆。

0

大部分的C标准库的使用策略,仅在位置通过返回true(或1)上的成功和假(或0)失败,并存储结果。比“失败”更具体的错误代码存储在特殊变量errno中。

类似于这样的int add(int* result, int a, int b),它在*结果中存储+ b并返回1(或返回0并将errno设置为合适的值,例如,如果a + b恰好大于maxint)。

相关问题