Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!pasteur!ames!lll-winken!uunet!auspex!guy From: guy@auspex.auspex.com (Guy Harris) Newsgroups: comp.lang.c Subject: Re: Why does lint complain about this? Message-ID: <1518@auspex.auspex.com> Date: 1 May 89 19:38:03 GMT References: <75688@ti-csl.csc.ti.com> <1773@ubu.warwick.UUCP> <8660@xanth.cs.odu.edu> Reply-To: guy@auspex.auspex.com (Guy Harris) Organization: Auspex Systems, Santa Clara Lines: 50 >Prototypes are very helpful in error checking, but it is an unwise practice >to *depend* on the compiler to do your casting for you. Unless you're working with a compiler that supports prototypes, in which case if the compiler won't do the conversions for you, it has what is technically known as a "bug". >If a function call would need an explicit cast to work correctly in >the absence of a prototype, then it should have an explicit cast. That's a stylistic matter - it doesn't *have* to have an explicit case if your compiler supports prototypes, but if it makes you feel better to explicitly cast the argument, go ahead and do so. >One of the more common errors of this type (pun intended) occurs frequently >in UNIX exec calls: > > execl(path, arg0, arg1, arg2, 0); /* non-portable */ > >instead of > > execl(path, arg0, arg1, arg2, (char *)0); ...which is not a good example, since "execl" is a function with a variable number of arguments and, as such, cannot have the types of all its arguments properly described by a prototype - you have to put in an ellipsis. As such, the compiler *cannot* (without extensions beyond the scope of ANSI C) know that all arguments to "execl" should have type "char *", and cannot convert a naked "0" to "(char *)0" in a call. Another common error is setbuf(file, 0); /* or NULL */ which the compiler *can* handle with prototypes, since the prototype for "setbuf" is: void setbuf(FILE *stream, char *buf); so it *does* know that the second argument should have type "char *". The only problem I can see with trusting prototypes if you're never going to use a compiler that doesn't support them is that you might not have the proper prototype in scope. This is a quality-of-implementation issue: the compiler *should* have a mode in which it warns of legal but questionable constructs such as calls to a function with no prototype in scope, non-prototype definitions of functions, etc.. There should also be a "lint" to check for problems that the compiler won't complain about....