我正在研究一些产生大量代码的代码
ignoring return value of ‘size_t fwrite(const void*, size_t, size_t, FILE*)’, declared with attribute warn_unused_result
使用g ++编译时出现警告,我想知道实际记录和处理大量单独顺序fwrite
s 的返回值的最佳编程模式(即fwrite
在循环中不一样)
让我们说代码现在看起来像这样:
fwrite (&blah, sizeof (blah), 1, fp); // ... more code ... fwrite (&foo, sizeof (foo), 1, fp); // ... more code ...
我正在考虑这样的事情,但我可能很难清理文件指针:
if (fwrite (&blah, sizeof (blah), 1, fp) != 1) return someerrorcode; // ... more code ... if (fwrite (&foo, sizeof (foo), 1, fp) != 1) return someerrorcode; // ... more code ...
我认为这种方法显然比嵌套更好,这太疯狂了:
if (fwrite (&blah, sizeof (blah), 1, fp) == 1) { // ... more code ... if (fwrite (&foo, sizeof (foo), 1, fp) == 1) {; // ... more code ... } }
当然,对于这种事情,已经有了既定的最佳实践模式?
当然,因为我主要研究这个以摆脱编译器警告,我可以将返回值分配给虚拟变量并忽略它,但我想先尝试以正确的方式进行.
dummy = fwrite (&blah, sizeof (blah), 1, fp); // ... more code ... dummy = fwrite (&foo, sizeof (foo), 1, fp); // ... more code ...
更新:我删除了c ++标签,因为这段代码实际上只是用g ++编译,所以需要基于c的解决方案来保持代码库的其余部分.
基于goto的穷人的C异常处理(实际上,goto的唯一实例不是有害的):
int foo() { FILE * fp = fopen(...); .... /* Note: fwrite returns the number of elements written, not bytes! */ if (fwrite (&blah, sizeof (blah), 1, fp) != 1) goto error1; ... if (fwrite (&foo, sizeof (foo), 1, fp) != 1) goto error2; ... ok: /* Everything went fine */ fclose(fp); return 0; error1: /* Error case 1 */ fclose(fp); return -1; error2: /* Error case 2 */ fclose(fp); return -2; }
你明白了.根据需要进行重组(单次/多次返回,单次清理,自定义错误消息等).根据我的经验,这是最常见的C错误处理模式.关键点是:永远不要忽略stdlib返回代码,任何这样做的好理由(例如可读性)都不够好.
我会沿着这些方向做点什么:
FILE * file = fopen("foo", "wb"); if(!file) return FAILURE; // assume failure by default _Bool success = 0; do { if(!fwrite(&bar, sizeof(bar), 1, file)) break; // [...] if(!fwrite(&baz, sizeof(baz), 1, file)) break; // [...] success = 1; } while(0); fclose(file); return success ? SUCCESS : FAILURE;
带着一点点C99宏魔法
#define with(SUBJECT, FINALIZE, ...) do { \ if(SUBJECT) do { __VA_ARGS__ } while(0); if(SUBJECT) FINALIZE; \ } while(0)
并且使用ferror()
Jonathan Leffler建议的代替我们自己的错误标志,这可以写成
FILE * file = fopen("foo", "wb"); with(file, fclose(file), { if(!fwrite(&bar, sizeof(bar), 1, file)) break; // [...] if(!fwrite(&baz, sizeof(baz), 1, file)) break; // [...] }); return file && !ferror(file) ? SUCCESS : FAILURE;
如果除了io错误之外还有其他错误条件,您仍然必须使用一个或多个错误变量跟踪它们.
此外,您的检查sizeof(blah)
是错误的:fwrite()
返回写入的对象的数量!