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 function:
uint32_t foo( void );
And let's say that I delibertly ignore the return value of the function. To make the warning dissapear, one can write
(void) foo();
My question is, what is the "proper" way to write code like this, should I continue as I always did, since the compiler doesn't complain about it, or should I use the void for clarity, so other code maintainer will know that I delibertly ignored the return value.
When I look at the code like this ( with the void ), it looks pretty strange to me...
One slightly more "beautiful" way of indicating unused results would be this:
With
C++
, this may be extended to: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:
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.
Other solution would be to actually use a value. Then you could remove the
unused variable
warning with a macro.Then in your example, you'd have:
For a static code checker to be useful, it should report also the ignored return values, which can lead very often to difficult to track errors - or missing error handling.
So you should keep the
(void)
or deactivate the check forprintf
. Now you have several options for doing it in a readable manner. I use to wrap the function inside a new function like for examplewhere the not so nice cast takes place. Perhaps it's more practical to do it using a preprocessor macro in this case because of the varargs...