Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

using "(void)" casts to purposefully ignore return values



At Wed, 24 Aug 2011 00:22:58 +0200, Marc Balmer <mbalmer%NetBSD.org@localhost> 
wrote:
Subject: Re: Possible unsafe use of strncat in sbin/sysctl/sysctl.c
> 
> But that is kind of, well, unneeded.  A compiler can detect that I don't
> use the return value by seeing that I don't use the return value.
> 
> Why tell the compiler that I don't want to use the return value?  It's a
> stupid rule, to say the least.

I have to disagree rather strongly, but with caveats.  :-)

The _first_ and _primary_ reason for putting "(void)" casts on function
calls is to note to other _human_ readers that you know what you're
doing when you ignore/discard the offered return value of a function
call.

The fact that lint (or some compiler warning) makes use of this
information and can then tell you about places where you forgot to check
the return value is a secondary benefit; and it is a real and
significant benefit to be sure.

Try not to think of it as something to shut off lint warnings!  Think of
it as information for future readers and maintainers.

Where it gets tedious of course though is with functions which offer a
return value but which by convention one can usually safely ignore.  The
CERT secure coding guidelines have this to say about that:

       If a function cannot fail or if the return value cannot signify
       an error condition, the return value may be ignored.  Such
       functions should be added to a white list when automatic checkers
       are used.

So, e.g., most of the str*() family could be white-listed, plus many
others.

Also, if the response to an error would rightfully be no different than
the response to success, there is no point in checking a return value,
and if that's common to all uses of a function in a given source module
then a single white-list hint for lint can save some typing and make the
code more readable.

Unfortunately our current version of lint does not include any facility
to white-list functions which return a value that can usually be ignored.

Thus my mention of "caveats" above.  :-)


Perhaps we would could teach lint about GCC attributes and then tag all
the functions which have the sole purpose of returning a useful value
with __attribute__((warn_unused_result)), then it could usually ignore
the rest by default.  You wouldn't need to use lint so much then either
-- the compiler warnings would often suffice.

You also wouldn't need to use both GCC attributes and lint comments to
mark unused parameters, non-returning functions, etc. either.


There are potential problems of course with any technique that makes the
analysis tools work better.  They could just end up introducing as much
noise as something like the use of "unnecessary" void casts on function
results; and if they don't do that then they can instead be misleading
to humans readers and more error prone to use as well.

The key might be the reversing of the sense of the lint heuristic about
ignored return values from the current draconian universal rule applying
to all functions all of the time to one implied by the
warn_unused_result attribute which would only be used on functions which
should never have their return value ignored.  That way one can worry
first and foremost about functions which must have their return value
used to be of any use (be they values like pointers to allocated
storage, computational results, or error codes that really must always
be checked for safe and secure operation) and worry less about functions
where the error code or result value is secondary and not always useful.
This might help both the human reader and the static analysis tools.

Adding a "no_warn_unused_result" function attribute might also be
helpful for lint since one could turn back on the strict full
return-code checking heuristic and still not be blasted about warnings
for functions like strcat() and printf().  This way functions which
return error codes, but where the error code may not be useful, could be
left without attributes and lint (and/or the compiler) could then warn
if their value is not used, but only at a very high warning level.

-- 
                                                Greg A. Woods
                                                Planix, Inc.

<woods%planix.com@localhost>       +1 250 762-7675        http://www.planix.com/

Attachment: pgpGF7srDAsWp.pgp
Description: PGP signature



Home | Main Index | Thread Index | Old Index