In a test, I'm discarding anything from stderr
since it clutters the output of the test case. I'm using the following code:
freopen("/dev/null", "w", stderr);
When compiling with -Wall -Werror
, I get the error
error: ignoring return value of ‘freopen’, declared with attribute warn_unused_result
which is expected. However, the usual solution of casting to void
doesn't seem to work. That is, changing the code to
(void) freopen("/dev/null", "w", stderr);
still produces the same warning. I don't care if this function fails since the worst case scenario is a bit of extra output. Any other way I can fix this?
EDIT: I know I could introduce an extra unnecessary variable. I would really like to know why casting to void doesn't work.
UPDATE: I decided to go with this:
FILE *null = fopen("/dev/null", "w");
if (null) { fclose(stderr); stderr = null; }
After reading the freopen
documentation more carefully, I see that if opening /dev/null
fails, stderr
will still be destroyed. This solves that problem.
A little heavy on the GCC extensions, but no externally visible variables:
#define ignore_result(x) ({ typeof(x) z = x; (void)sizeof z; })
ignore_result(freopen("/dev/null", "w", stderr));
Why not simply use the result, as the warning suggests you should.
if (freopen("/dev/null", "w", stderr) == 0)
...oops...lost stderr...hard to report errors...
Since the function is declared with the 'warn_unused_result' attribute, you will get the warning unless you use the return value. Since the function either returns null on failure or the file stream argument on success, you might think about assigning the result. However, you should not assign to stderr like that (see below), so this is a bad idea:
stderr = freopen("/dev/null", "w", stderr);
Theoretically, you should make that check; there are dire (and implausible) circumstances under which you could fail to open "/dev/null".
Footnote 229 in the C99 standard notes:
229) The primary use of the
freopen
function is to change the file associated with a standard text stream (stderr
,stdin
, orstdout
), as those identifiers need not be modifiable lvalues to which the value returned by thefopen
function may be assigned.
Therefore, the assignment is ill-advised. But testing the return value would deal with the compiler warning and might help prevent core dumps too. It is unlikely to improve your code coverage figures, though (the error path is not going be taken very often; it will be hard to force coverage of the error handling).
Note that the POSIX description of freopen()
has some moderately caustic comments about the design of freopen()
, which was invented by the C standard committee (1989 version), presumably without input from POSIX.
int tossmeout = freopen("/dev/null", "w", stderr);
As comments below try
FILE *tossmeout = freopen("/dev/null", "w", stderr);
and
(void *)freopen("/dev/null", "w", stderr);
If you really have to use the C language (not C++) then you may use this workaround:
inline void ignore_result_helper(int __attribute__((unused)) dummy, ...)
{
}
#define IGNORE_RESULT(X) ignore_result_helper(0, (X))
For example
typedef struct A
{
int x;
} A;
__attribute__((warn_unused_result)) A GetA()
{
A const a;
return a;
}
int main()
{
IGNORE_RESULT(GetA());
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With