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.
Why not simply use the result, as the warning suggests you should.
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:
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:
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 offreopen(), which was invented by the C standard committee (1989 version), presumably without input from POSIX.