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