Lately, I started using lint for static code analysis. One of the warning I get sometimes is regarding this issue. Let\'s say for instance that I\'ve got the following funct
Usually there are not too many functions the value of which you want to ignore. Splint, for example, allows to add a special comment that would let it know, that a return value of a specific function might be ignored. Unfortunately, this in effect disables all 'ignored returned value' warning related to that particular function.
Here is an example of Splint-clean program:
#include <stdio.h>
FILE /*@alt void@*/ *fopen(const char *path, const char *mode);
static int /*@alt void@*/ test(void)
{
printf( "test called\n" );
fopen( "test", "a" );
return 0;
}
int main(void)
{
test();
return 0;
}
The unpleasant part is that you need to add an additional prototype to a system function with a comment somewhere.
Btw,by default Splint doesn't complain about the return value of printf
and of some other libc functions being unused. However, a stricter mode can be activated.
LINT allows something similar, but I have never used it. Here is what a documentation says.
LINT lets you mark functions with optional return values by using a directive similar to the #directives of the C preprocessor.
#pragma optresult
can be placed immediately before the definition of a function that returns an optional result. LINT then recognizes that this function returns a result that can be ignored; LINT does not give error messages if the result is ignored.
The common way is to just call foo();
without casting into (void)
.
He who has never ignored printf()
's return value, cast the first stone.
One way to do this with Clang and GCC compilers is with a pragma
:
/* ... */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
foo(); /* this specific unused-result warning gets ignored during compilation */
#pragma GCC diagnostic pop
/* ... */
The push
-pop
combination wraps the ignored
directive so that warnings can be triggered elsewhere in your code. It should be easier for anyone reading your source code down the road to see what this code block does.
It is entirely legal and acceptable to write code that ignores the return value in some cases. The program below has very little reason to check the return value of printf().
int main(void) {
printf("Hello world\n");
return 0;
}
gnulib has this: http://git.savannah.gnu.org/cgit/gnulib.git/tree/lib/ignore-value.h
/* Normally casting an expression to void discards its value, but GCC
versions 3.4 and newer have __attribute__ ((__warn_unused_result__))
which may cause unwanted diagnostics in that case. Use __typeof__
and __extension__ to work around the problem, if the workaround is
known to be needed. */
#if 3 < __GNUC__ + (4 <= __GNUC_MINOR__)
# define ignore_value(x) \
(__extension__ ({ __typeof__ (x) __x = (x); (void) __x; }))
#else
# define ignore_value(x) ((void) (x))
#endif
One slightly more "beautiful" way of indicating unused results would be this:
/**
* Wrapping your function call with ignore_result makes it more clear to
* readers, compilers and linters that you are, in fact, ignoring the
* function's return value on purpose.
*/
static inline void ignore_result(long long int unused_result) {
(void) unused_result;
}
...
ignore_result(foo());
With C++
, this may be extended to:
template<typename T>
inline void ignore_result(const T & /* unused result */) {}