是否值得检查不应失败的方法的返回码?
例如,我通常会这样做:
char buf[MAXBUF];
snprintf(buf, sizeof(MAXBUF), "%s.%d", str, time);
即使我知道,检查snprintf的返回码也是一种好习惯 MAXBUF足够大我的目的?这样做似乎很有意义 即使代码变得更加冗长。
答案 0 :(得分:4)
简答:是的
长答案:是的,因为它捕获了如下的愚蠢错误。
char buf[MAXBUF];
snprintf(buf, sizeof(MAXBUF), "%s.%d", str, time);
// sizeof(MAXBUF) is probably equal to sizeof(int)
C代码的主要问题是人们实际上没有检查返回代码(因为他们认为代码永远不会失败)。所以故事的寓意是不要假设和检查。它实际上并没有给代码增加太多。你可能应该退出/中止,如果不应该出错的东西实际出错,那么你会在测试周期的早期找到它们。
C ++解决方案:
std::stringstream buf;
buf << str << "." << time; // No chance of error as compiler does the work.
答案 1 :(得分:2)
这取决于。有可能MAXBUF
或格式字符串或输入值将来会发生变化吗?如果呼叫失败,您的代码可以采取什么现实的行动?答案完全取决于您的申请。
一种可能性是简单地assert
返回值是预期的,而不是静默失败。这将在生产版本中花费您的任何费用,并且对源代码的详细程度几乎不会增加。
答案 2 :(得分:0)
这可能是最好的,只是因为,但如果你确定不会超过MAXBUF的大小,那么它只会增加几个时钟周期。
答案 3 :(得分:0)
在编写代码时,您正在权衡一次简单错误检查的一次性成本,而不是根据上下文决定是否检查它的重复成本,如果没有,则由于误解的假设或以后的维护而导致可能的生产错误由其他人。
在大多数情况下,这是毫无疑问的。
答案 4 :(得分:0)
如果缓冲区太小,那么字符串将被截断。你希望你的测试能够抓住这个,因为你会产生不正确的结果。
然后再次检查返回值不需要添加太多冗长的内容。正如奥利所说,assert
很便宜:
int result = snprintf(buf, sizeof buf, "%s.%d", str, time);
assert(result >= 0 && result <= (sizeof buf) - 1);
说实话,我不会经常检查,但这取决于我认为str
不能那么久的原因。如果这是一个非常根本的原因(比如它来自dirent
结构的文件名,而MAXBUF
是根据MAX_FILENAME
定义的),那么我可能不会打扰。如果是因为在其他地方有一些检查,或者调用者有责任传入一个只有一定长度的字符串,那么assert
可能是一个想法,只是因为有一天会抓住别人的错误。 。显然,如果str
是任何未经检查的外部输入,则必须进行测试。