我正在研究一些产生大量代码的代码
ignoring return value of ‘size_t fwrite(const void*, size_t, size_t, FILE*)’, declared with attribute warn_unused_result
Run Code Online (Sandbox Code Playgroud)
使用g ++编译时出现警告,我想知道实际记录和处理大量单独顺序fwrites 的返回值的最佳编程模式(即fwrite在循环中不一样)
让我们说代码现在看起来像这样:
fwrite (&blah, sizeof (blah), 1, fp);
// ... more code ...
fwrite (&foo, sizeof (foo), 1, fp);
// ... more code ...
Run Code Online (Sandbox Code Playgroud)
我正在考虑这样的事情,但我可能很难清理文件指针:
if (fwrite (&blah, sizeof (blah), 1, fp) != 1) return someerrorcode;
// ... more code ...
if (fwrite (&foo, sizeof (foo), 1, fp) != 1) return someerrorcode;
// ... more code ...
Run Code Online (Sandbox Code Playgroud)
我认为这种方法显然比嵌套更好,这太疯狂了:
if (fwrite (&blah, sizeof (blah), 1, fp) == 1) {
// ... more code ...
if (fwrite (&foo, sizeof (foo), 1, fp) == 1) {;
// ... more code ...
}
}
Run Code Online (Sandbox Code Playgroud)
当然,对于这种事情,已经有了既定的最佳实践模式?
当然,因为我主要研究这个以摆脱编译器警告,我可以将返回值分配给虚拟变量并忽略它,但我想先尝试以正确的方式进行.
dummy = fwrite (&blah, sizeof (blah), 1, fp);
// ... more code ...
dummy = fwrite (&foo, sizeof (foo), 1, fp);
// ... more code ...
Run Code Online (Sandbox Code Playgroud)
更新:我删除了c ++标签,因为这段代码实际上只是用g ++编译,所以需要基于c的解决方案来保持代码库的其余部分.
fbo*_*net 10
基于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;
}
Run Code Online (Sandbox Code Playgroud)
你明白了.根据需要进行重组(单次/多次返回,单次清理,自定义错误消息等).根据我的经验,这是最常见的C错误处理模式.关键点是:永远不要忽略stdlib返回代码,任何这样做的好理由(例如可读性)都不够好.
Chr*_*oph 10
我会沿着这些方向做点什么:
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;
Run Code Online (Sandbox Code Playgroud)
带着一点点C99宏魔法
#define with(SUBJECT, FINALIZE, ...) do { \
if(SUBJECT) do { __VA_ARGS__ } while(0); if(SUBJECT) FINALIZE; \
} while(0)
Run Code Online (Sandbox Code Playgroud)
并且使用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;
Run Code Online (Sandbox Code Playgroud)
如果除了io错误之外还有其他错误条件,您仍然必须使用一个或多个错误变量跟踪它们.
此外,您的检查sizeof(blah)是错误的:fwrite()返回写入的对象的数量!