在测试中,我丢弃stderr
中的任何内容,因为它会使测试用例的输出变得混乱。我正在使用以下代码:
freopen("/dev/null", "w", stderr);
使用-Wall -Werror
进行编译时,出现错误
error: ignoring return value of ‘freopen’, declared with attribute warn_unused_result
这是预料之中的。但是,通常的void
投射解决方案似乎不起作用。也就是说,将代码更改为
(void) freopen("/dev/null", "w", stderr);
仍会产生相同的警告。我不在乎这个函数是否失败,因为最坏的情况是一些额外的输出。还有其他方法可以解决这个问题吗?
编辑:我知道我可以引入额外的不必要变量。我真的很想知道为什么施放到无效是不行的。
更新 我决定这样做:
FILE *null = fopen("/dev/null", "w");
if (null) { fclose(stderr); stderr = null; }
在仔细阅读freopen
文档后,我发现如果打开/dev/null
失败,stderr
仍将被销毁。这解决了这个问题。
答案 0 :(得分:11)
GCC扩展有点重,但没有外部可见的变量:
#define ignore_result(x) ({ typeof(x) z = x; (void)sizeof z; })
ignore_result(freopen("/dev/null", "w", stderr));
答案 1 :(得分:6)
为什么不简单地使用结果,因为警告建议你应该这样做。
if (freopen("/dev/null", "w", stderr) == 0)
...oops...lost stderr...hard to report errors...
由于函数是使用'warn_unused_result'属性声明的,因此除非使用返回值,否则将收到警告。由于函数在失败时返回null或在成功时返回文件流参数,因此您可能会考虑分配结果。但是,你不应该 像那样分配给stderr(见下文),所以这是一个坏主意:
stderr = freopen("/dev/null", "w", stderr);
理论上,你应该做那个检查;存在可能无法打开“/ dev / null”的可怕(并且难以置信)的情况。
C99标准中的脚注229注释:
229)
freopen
函数的主要用途是更改与标准文本流关联的文件 (stderr
,stdin
或stdout
),因为这些标识符不一定是值可修改的左值 可以分配由fopen
函数返回的。
因此,这项任务是不明智的。但是测试返回值会处理编译器警告,也可能有助于防止核心转储。但是,它不太可能改善您的代码覆盖率数据(错误路径不会经常使用;很难强制覆盖错误处理)。
请注意freopen()
的POSIX描述对freopen()
的设计有一些适度的刻薄评论,这是由C标准委员会(1989版)发明的,可能没有来自POSIX的输入。
答案 2 :(得分:2)
int tossmeout = freopen("/dev/null", "w", stderr);
如下面的评论尝试
FILE *tossmeout = freopen("/dev/null", "w", stderr);
和
(void *)freopen("/dev/null", "w", stderr);
答案 3 :(得分:2)
如果你真的必须使用C语言(而不是C ++),那么你可以使用这个解决方法:
inline void ignore_result_helper(int __attribute__((unused)) dummy, ...)
{
}
#define IGNORE_RESULT(X) ignore_result_helper(0, (X))
例如
typedef struct A
{
int x;
} A;
__attribute__((warn_unused_result)) A GetA()
{
A const a;
return a;
}
int main()
{
IGNORE_RESULT(GetA());
return 0;
}