我想知道是否检查我们为生产环境编写的所有函数的返回码。 对于e,g,我经常使用C并且你也会捕获标准库的返回码,而不仅仅是你编写的函数,还有第三方API /标准库/任何其他库。
我在制作中看到的大多数代码都没有这样做。 所以我的问题是那些在生产环境中工作并且已经编写了大约20年左右的生产代码的有经验的人。 您是否从第三方API /标准库/任何其他库中获取返回代码,而不仅仅是您实现的函数? 只是为了说明我的意思 你是否抓住C标准库的C标准lib函数(snprintf / sprintf,strncat / strcat等等,...)的返回码。
感谢您的所有回复。
答案 0 :(得分:3)
我认为你不应该对此采取全有或全无的方法。当期望函数调用出现问题时捕获返回/错误代码(当然,如果后续计算取决于函数返回的内容)。但是,如果您非常确定该调用不会导致错误(或者您甚至没有使用返回值),执行跳过捕获返回值。
这是个人工程判断的一个领域,而不是某些规定的“最佳实践”。此外,我认为同样的想法将适用于异常处理。
答案 1 :(得分:3)
我花了很长时间才学到这一点,但除了少数例外,您应该始终检查函数的返回代码。
我已经看到太多调用malloc
的代码(例如)并且只是愉快地使用它返回的指针。 99.9%的时间,这不是问题,但偶尔malloc
将失败,并且当您尝试取消引用NULL指针时程序将崩溃。现在,有人可能会争辩说,如果malloc
仍然返回NULL,你想要退出 - 这可能是真的,但你应该努力优雅地退出,即使是致命的错误。
所以,是的:检查返回代码。不要假设某些东西只是因为它总是在过去起作用。事情总是失败。通过防御性编码,检查错误,检查errno
,输出strerror
并优雅地失败,您将节省大量时间和悲伤。
答案 2 :(得分:2)
如果函数可能返回错误代码 - 请务必检查并处理它,就像这样简单。这个规则可以在寻找漏洞时节省大量时间。
如果函数总是返回无法指示错误的代码而您不需要结果(例如printf
),那么您可以忽略它。
答案 3 :(得分:2)
是的,除非极少数例外,您的程序应始终检查并处理错误返回值,即使(特别是)您不希望出现任何错误。毕竟,我们软件的环境通常不如我们希望的那样可靠。
在本质上,这就是大多数现代语言都有例外的原因:除其他外,它们为您未明确处理(即捕获)的错误提供“默认错误处理程序”(中止和堆栈跟踪)。它们还允许集中错误处理,而不是检查每个函数调用的返回值。
答案 4 :(得分:1)
如果函数返回错误代码,则调用代码应该决定如何处理错误。对于某些程序,忽略错误可能没问题;例如,当写入stderr时,这往往是人们对标准I / O库中的错误所做的事情。 (如果消息失败,你能做什么?退出?你还在做什么吗?)
一个令人讨厌的来源是记录为返回值但始终返回相同值(通常为0)的函数。通常,这些是在void
返回之前最初用K& R C编写的函数。它们已转换为int
,然后添加了“return(0);
”以平息有关“函数不返回值”的警告,而不是将其转换为void
。这些职能应修改为void
;在过渡期间,可以忽略它们的错误返回值。
我不同意另一个答案中的观察结果“当您预期函数调用出现问题时捕获返回/错误代码”。问题正是出乎意料的是杀死了你。即使最稳定的操作也可能意外失败(可能是DBMS崩溃了,所以即使你有连接,也不再有了),而且你的软件必须识别并处理这些问题。
答案 5 :(得分:0)
snprintf
很有用,因为您可能想要分配更大的缓冲区然后重试,或者您可能按顺序调用它:
// cons lists as [a,b,c, ...]
if ( type == kin_cons_class() ) {
size_t offs = snprintf ( buf, max, "[" );
if ( offs >= max )
return nul_terminate ( buf, offs, max );
size_t count = depth;
kin_cons_ref_t empty = kin_cons_nil();
kin_cons_ref_t cons;
for ( cons = ref; cons != empty; cons = kin_cons_tail ( cons ) ) {
if ( count > 15 ) {
offs += snprintf ( buf + offs, max - offs, ", ..." );
break;
}
if ( cons != ref ) {
offs += snprintf ( buf + offs, max - offs, "," );
if ( offs >= max )
return nul_terminate ( buf, offs, max );
}
offs += string_repr ( buf + offs, max - offs, kin_cons_head ( cons ), depth, escape_strings );
if ( offs >= max )
return nul_terminate ( buf, offs, max );
++count;
}
if ( offs >= max )
return nul_terminate ( buf, offs, max );
offs += snprintf ( buf + offs, max - offs, "]" );
return nul_terminate ( buf, offs, max );
}
如果你继续进行所有的offs >= max
测试,就会出现缓冲区溢出,并且会出现段错误。
printf
不会发生这种情况,因此检查返回时不太常见。
如果您需要根据功能是否有效来改变行为,请检查返回。许多标准库函数可能会失败,或者稍后会导致未定义的行为,因此您需要检查这些返回。
如果您不需要根据返回值更改行为,那么检查它是没有意义的。