Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!usc!snorkelwacker.mit.edu!bloom-picayune.mit.edu!news From: scs@adam.mit.edu (Steve Summit) Newsgroups: comp.lang.c Subject: Re: lint (was: Funny mistake) Summary: scs rants about prototypes again Message-ID: <1991Mar23.043408.5260@athena.mit.edu> Date: 23 Mar 91 04:34:08 GMT References: <13619@helios.TAMU.EDU> <5036@goanna.cs.rmit.oz.au> <13627@helios.TAMU.EDU> Sender: news@athena.mit.edu (News system) Reply-To: scs@adam.mit.edu Organization: Thermal Technologies, Cambridge, MA Lines: 75 In article <13627@helios.TAMU.EDU> byron@archone.tamu.edu (Byron Rakitzis) writes: >In article <5036@goanna.cs.rmit.oz.au> ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) writes: >>But will your hand-holding compiler check that a *group* of files are >>consistent? That's what I really depend on lint for. > >I don't see what you need over and above good function-prototype checking. >I am going to write a compiler strongly biased towards ANSI C; if you don't >supply prototypes, you will pay the price of not having the use of >unprototyped functions checked for type safety. I don't believe that ANSI C prototypes, as currently defined and commonly implemented, are a sufficient solution to the problem of cross-file declaration mismatches. One could also say, "if you don't supply correct function calls, you will pay the price of not having your code work properly." The analogy is imperfect, but not absurd. Keeping function calls correct across source files is tedious and error-prone. Lint was developed in part as an acknowledgement that even conscientious programmers make mistakes, which an automated tool can catch. Perfect (or infinitely patient) programmers wouldn't need lint. Prototypes catch almost as many errors as lint would (they don't check data declarations), but they can also gloss over other potential errors (by quietly inserting casts to the correct type), and they do their work only when the programmer has gone to the considerable extra work of supplying the prototypes and keeping them up-to-date. I do use full prototypes in some programs, and it's a lot of work. It galls me that I have to do all this work, to get 90% of the checking that a simple invocation of lint would do automatically. (It's also annoying that catching errors with the aid of prototypes is essentially a two-pass affair: first you have to chase down all the "function called with no prototype in scope" warnings, and supply the missing prototypes so that a second pass can use them to check your calls. How would you like it if you had to give a spellchecking program a list of the correctly-spelled words in the document to be checked?) The use of prototypes can also dramatically increase recompilation during development, because prototypes *must* be placed in header files (see below), so you need lots of header files (up to one per C source file), and they must be much more widely #included. (It's true that in a carefully planned and properly managed project, changes or additions to module interfaces, and therefore changes to prototypes and header files, should be infrequent. On the other hand, incremental design and implementation is not without its merits, and new interfaces can be added all the time.) All prototypes (except those for static functions) must be placed in header (.h) files, and *not* in source (.c) files, so that the header file can be #included both by the referencing source files and by the defining source file, so that the prototype (and in particular, the same copy of it) can be checked against the definition. This is reasonably obvious if you think about it. However, I suspect that there are a lot of beginning or incautious programmers who are typing prototypes directly in at the top of the .c files in which they are needed. (Programming textbooks usually talk about functions before they talk about #include, so their early examples suggest and reinforce this habit.) If there is any chance that the function definitions are going to change, decoupled prototypes like these are worse than useless. They would have to be manually kept in sync with the definitions, which is what we agreed, back at square one (talking about manually keeping calls in sync with definitions), is difficult for people to do. I'm not trying to start a lint vs. prototypes flamefest here. Prototypes have their advantages, and they're definitely here to stay. But they're not a panacea. Steve Summit scs@adam.mit.edu