tags:

views:

71

answers:

3

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.

+2  A: 
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);
Hogan
Sure. But is there a way to do this without creating an unnecessary variable?
Michael Mior
Also, `freopen` returns `FILE*`.
dreamlax
@Michael : most compilers won't "create" a variable -- they just put it in a symbol table and only reserve space for it if it is referenced. -- they *might* be lazy increment the stack pointer for local storage.
Hogan
+1  A: 

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));
Huw Giddens
+4  A: 

Why not simply use the result, as the warning suggests you should:

stderr = freopen("/dev/null", "w", stderr);

Since the function is declared with the 'warn_unused_result' attribute, you will get the warning unless you use the return value. Alternatively, if you are unhappy about assigning to stderr like that (and you should be; see below), you could test whether the return is null:

if (freopen("/dev/null", "w", stderr) == 0)
    ...oops...lost stderr...hard to report errors...

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, or stdout), as those identifiers need not be modifiable lvalues to which the value returned by the fopen function may be assigned.

Therefore, the first line 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.

Jonathan Leffler
Thanks. You make a good point.
Michael Mior