ck@voa3.UUCP (Chris Kern) (11/17/89)
I suspect this is not a novel inquiry, but I can't remember any previous discussion. . . . My compiler (pcc) is agnostic about discarding the value from a function call. Lint, of course, protests. If it's my function, I presumably will declare it to be void if it doesn't return a value and will use the value if it does return one. But what about a standard library function whose value I (perhaps recklessly) wish to ignore? Should I cast the function call to void, or am I just indulging in the trivial luxury of silencing lint? -- Chris Kern Voice of America, Washington, D.C. ...uunet!voa3!ck +1 202-485-7020
sullivan@aqdata.uucp (Michael T. Sullivan) (11/17/89)
From article <316@voa3.UUCP>, by ck@voa3.UUCP (Chris Kern): > ... Should I cast the function > call to void, or am I just indulging in the trivial luxury of > silencing lint? Although you are merely silencing lint, you are also doing yourself a service. If you start letting warnings like "return value ignored" pop up then you will someday miss an real warning/error message that is buried amongst the "fake" warning/error messages. Silence as many lint warnings as you can (will somebody PLEASE do something about the malloc bugaboo) and the real ones will stand out easily. -- Michael Sullivan uunet!jarthur.uucp!aqdata!sullivan aQdata, Inc. San Dimas, CA
gwyn@smoke.BRL.MIL (Doug Gwyn) (11/17/89)
In article <316@voa3.UUCP> ck@voa3.UUCP (Chris Kern) writes: >But what about a standard library function whose value I >(perhaps recklessly) wish to ignore? Should I cast the function >call to void, or am I just indulging in the trivial luxury of >silencing lint? C does not require the (void) cast of the unused return value. As a matter of policy, you shouldn't do things JUST to "shut lint up". Lint is warning you that functions return success status etc. by design and that it may be unwise to fail to check the returned status. Therefore, I would say that for each such warning you should THINK whether or not the returned value is important for the context in which the function is invoked, and if so do something about it, or if not then explicitly discard the value with a (void) cast. If you follow that policy, then the reader of your code will KNOW that (void) means that you've thought about it and decided the return value was not needed. Without the explicit (void) he would have no way to tell if there had been an oversight.
duane@anasaz.UUCP (Duane Morse) (11/18/89)
In article <316@voa3.UUCP>, ck@voa3.UUCP (Chris Kern) writes:
[ My compiler (pcc) is agnostic about discarding the value from a
[ function call. Lint, of course, protests.
[ If it's my function, I presumably will declare it to be void if
[ it doesn't return a value and will use the value if it does return
[ one. But what about a standard library function whose value I
[ (perhaps recklessly) wish to ignore? Should I cast the function
[ call to void, or am I just indulging in the trivial luxury of
[ silencing lint?
We've found that lint catches programmer bugs often enough to make it
worthwhile to do the casts of standard library functions, so much so
that we require all programs to 'pass' lint before they can be released.
Lint can point out bugs that would take a programmer hours to find,
so we believe there's no excuse _not_ to use lint.
--
Duane Morse e-mail: duane@anasaz (or ... asuvax!anasaz!duane)
(602) 861-7609
bill@twwells.com (T. William Wells) (11/18/89)
In article <1989Nov17.154621.2698@aqdata.uucp> sullivan@aqdata.uucp (Michael T. Sullivan) writes:
: From article <316@voa3.UUCP>, by ck@voa3.UUCP (Chris Kern):
: > ... Should I cast the function
: > call to void, or am I just indulging in the trivial luxury of
: > silencing lint?
:
: Although you are merely silencing lint, you are also doing yourself
: a service. If you start letting warnings like "return value ignored"
: pop up then you will someday miss an real warning/error message that
: is buried amongst the "fake" warning/error messages. Silence as many
: lint warnings as you can (will somebody PLEASE do something about the
: malloc bugaboo) and the real ones will stand out easily.
I don't worry about lint warnings about functions whose return
value is never used. It is generally a very short list, things
like strcpy and the like, where the return value is never of
interest to me. I use a cast to void when I ignore the return
value of a function whose return value is used elsewhere.
---
Bill { uunet | novavax | ankh | sunvice } !twwells!bill
bill@twwells.com
gwyn@smoke.BRL.MIL (Doug Gwyn) (11/19/89)
In article <1989Nov18.062322.12728@twwells.com> bill@twwells.com (T. William Wells) writes: >I don't worry about lint warnings about functions whose return >value is never used. It is generally a very short list, ... If it isn't a problem for you, more power to you. I find that I am less likely to overlook genuine problems reported by "lint" if NO lint output is expected than if SOME lint output is expected. This is difficult to enforce when malloc() is involved, although there are ways.
bill@twwells.com (T. William Wells) (11/20/89)
In article <11644@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: : In article <1989Nov18.062322.12728@twwells.com> bill@twwells.com (T. William Wells) writes: : >I don't worry about lint warnings about functions whose return : >value is never used. It is generally a very short list, ... : : If it isn't a problem for you, more power to you. Not so long as I keep the list *short*. : I find that I am less likely to overlook genuine problems : reported by "lint" if NO lint output is expected than if : SOME lint output is expected. This is difficult to enforce : when malloc() is involved, although there are ways. I've found that completely shutting up lint is not worth my time. Not that it is impossible, but I have better things to do. For example, read() and write(), on different machines, take either an unsigned int or an int as their third arguments; while one *could* set things up so that lint won't complain about this, why bother? Another gotcha is those irritating truncated long messages; at least one lint I've worked with won't stop them even if you use a cast. (And what is so irritating is that one *can't* ignore them.) Another irritation is the sizeof problem. Things that want a size should take an unsigned something (or a size_t). But sizeof often generates an int, which some lints complains about. Anyway, my approach to this is to shut lint up on anything where I might be confused by its output, and ignore the rest. (In one case, I got sufficiently irritated that I wrote a script to remove the noise. This is risky, unfortunately.) One thing that helps is that I do most of my work development at home on my sysV/386 and immediately port it to the Sun at work. (Typically, I develop it here at home and then run it there: 4MIPS bests ~2MIPS, especially when it takes two hours even at 4!) Porting is usually a copy, but I sometime catch errors that way. The real advantage is that, when coding, I am pretty much required to keep in mind that there are at *least* three other kinds of machines that my code *will* be run on. That is a real incentive to avoid those practices that lint would otherwise complain about. --- Bill { uunet | novavax | ankh | sunvice } !twwells!bill bill@twwells.com
jeffrey@algor2.algorists.com (Jeffrey Kegler) (11/20/89)
In article <11644@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: >In article <1989Nov18.062322.12728@twwells.com> bill@twwells.com (T. William Wells) writes: >>I don't worry about lint warnings about functions whose return >>value is never used. It is generally a very short list, ... > >If it isn't a problem for you, more power to you. >I find that I am less likely to overlook genuine problems >reported by "lint" if NO lint output is expected than if >SOME lint output is expected. This is difficult to enforce >when malloc() is involved, although there are ways. I always make lint produce silent output, even when writing device drivers. Even if you can remember which lint messages are harmless, someone inheriting your code has to examine them all, or ignore them all. And a few months later, if lint produces 7 messages instead of 6, I do not feel all that sure that 7th would catch my attention. One instead of zero, I will notice. -- Jeffrey Kegler, Independent UNIX Consultant, Algorists, Inc. jeffrey@algor2.ALGORISTS.COM or uunet!algor2!jeffrey 1762 Wainwright DR, Reston VA 22090
diamond@csl.sony.co.jp (Norman Diamond) (11/21/89)
In article <1989Nov19.171815.17445@twwells.com> bill@twwells.com (T. William Wells) writes: >I've found that completely shutting up lint is not worth my time. Agreed, but for the sake of curiosity... >Not that it is impossible, but I have better things to do. What DO you do about calls to malloc? -- Norman Diamond, Sony Corp. (diamond%ws.sony.junet@uunet.uu.net seems to work) Should the preceding opinions be caught or | James Bond asked his killed, the sender will disavow all knowledge | ATT rep for a source of their activities or whereabouts. | licence to "kill".
kremer@cs.odu.edu (Lloyd Kremer) (11/22/89)
The only way I've found to shut lint up about malloc calls is: lint | grep -v 'possible pointer alignment problem' Does anyone have a better way? Please share it with us so we can stop talking about this particular bugaboo. Lloyd Kremer kremer@cs.odu.edu Have terminal...will hack!
peter@ficc.uu.net (Peter da Silva) (11/22/89)
Wouldn't this be simpler? > #ifdef lint ! # define malloc(x) (x, 0) > #else > extern char *malloc(); > #endif -- `-_-' Peter da Silva <peter@ficc.uu.net> <peter@sugar.lonestar.org>. 'U` -------------- +1 713 274 5180. "I agree 0bNNNNN would have been nice, however, and I sure wish X3J11 had taken time off from rabbinical hairsplitting to add it." -- Tom Neff <tneff@bfmny0>
bill@twwells.com (T. William Wells) (11/22/89)
In article <11161@riks.csl.sony.co.jp> diamond@ws.sony.junet (Norman Diamond) writes:
: What DO you do about calls to malloc?
Something like:
extern void *real_alloc();
#ifdef lint
static void fake_alloc(n) unsigned n; { (void)real_alloc(n); }
#define myalloc(x) (fake_alloc(x), 0)
#else
#define myalloc(x) real_alloc(x)
#endif
When lint is not defined, myalloc just goes to real_alloc, which
does things like checking for out of memory after the call to
malloc.
When lint is defined, myalloc has the call to fake_alloc in order
to type check its argument, and the zero is what the cast that
goes with the myalloc sees. Lint doesn't mind casting the zero,
so there are no complaints.
---
Bill { uunet | novavax | ankh | sunvice } !twwells!bill
bill@twwells.com
kilroy@mimsy.umd.edu (Nancy's Sweetie) (11/23/89)
In article <11644@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: > I find that I am less likely to overlook genuine problems reported by > "lint" if NO lint output is expected than if SOME lint output is expected. > This is difficult to enforce when malloc() is involved, although there > are ways. With which I totally agree: shut up lint. Completely. In article <1989Nov19.171815.17445@twwells.com> bill@twwells.com (T. William Wells) writes: > >I've found that completely shutting up lint is not worth my time. >Not that it is impossible, but I have better things to do. and >Anyway, my approach to this is to shut lint up on anything where >I might be confused by its output, and ignore the rest. Which irritates me more than I can express. (Though I'll try anyway. 8-) At the NIH Department of Nuclear Medicine, I have to support a program which does real-time data aquisition. The original version of this program, I am told, `produced little output from lint.' It has since been modified 32 times. Each person who touched it made a little change here, a little change there, and never bothered to make sure they didn't add to the lint output. When I got this thing, I looked at it for a while, and then ran lint on it. I got back 851 lines of output, some of which said things like `67 lines deleted for lack of space.' Now, you may feel that you have better things to do, and you may feel that *you* are not confused by some of the messages. But if you don't care to put *hard work* into making your programs maintainable for the next guy who comes along, then why are you even bothering to write programs? I also have things to do besides spend a half hour ensuring that a program that works has all the lint-shutter-uppers in it. But a little hard work never killed anybody, especially if it can help the next person in line. Nobody will ever get *any* lines of output running lint on a program I've written, let alone ~800. kilroy@cs.umd.edu Darren F. Provine ...uunet!mimsy!kilroy "If everybody gives a little, everybody gets a lot." -- Pete Cottrell
bill@twwells.com (T. William Wells) (11/24/89)
In article <20882@mimsy.umd.edu> kilroy@mimsy.umd.edu (Nancy's Sweetie) writes: : In article <11644@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: : > I find that I am less likely to overlook genuine problems reported by : > "lint" if NO lint output is expected than if SOME lint output is expected. : > This is difficult to enforce when malloc() is involved, although there : > are ways. : : With which I totally agree: shut up lint. Completely. : : In article <1989Nov19.171815.17445@twwells.com> bill@twwells.com : (T. William Wells) writes: : > : >I've found that completely shutting up lint is not worth my time. : >Not that it is impossible, but I have better things to do. : : and : : >Anyway, my approach to this is to shut lint up on anything where : >I might be confused by its output, and ignore the rest. : : Which irritates me more than I can express. (Though I'll try anyway. 8-) : : [He then goes on to describe a program modified by a bunch of asshole : programmers.] If someone wants to take my code and do stupid things with it, I can't stop him. Even if I had written my code to be lintless, had they not used lint after each modification, it would be as bad as if I had left in lint warnings. : Now, you may feel that you have better things to do, and you may feel that : *you* are not confused by some of the messages. But if you don't care to : put *hard work* into making your programs maintainable for the next guy who : comes along, then why are you even bothering to write programs? Because, you asshole, I *do* put hard work into my programs. But there are are better things for me to do than to deal with this: function returns value which is always ignored fprintf umask putenv setgid setuid time signal strcpy unlink fflush printf sprintf strcat sleep fputs (The sum total of lint warnings from a program *under development*. I can tell you why *each* of these is there. And I can tell you, also, which I'm not going to get rid of in the production version.) (Why the obscenity? If people throw ad hominems at me, I feel it perfectly reasonable to return them in kind.) : I also have things to do besides spend a half hour ensuring that a program : that works has all the lint-shutter-uppers in it. But a little hard work : never killed anybody, especially if it can help the next person in line. : Nobody will ever get *any* lines of output running lint on a program I've : written, let alone ~800. EXCUSE me. If I have a half hour to spend, I have to decide on where it is best spent. Since I'm already chin deep in things to do, I'm not going to spend time on something that makes no significant difference. If the people who are working with your programs are competent, a few lint warnings will be easy enough for them to deal with. If they are not, nothing you can do will make a bit of difference. Followups have been directed to alt.flame. --- Bill { uunet | novavax | ankh | sunvice } !twwells!bill bill@twwells.com
gwyn@smoke.BRL.MIL (Doug Gwyn) (11/25/89)
In article <1989Nov23.233403.2841@twwells.com> bill@twwells.com (T. William Wells) writes: >function returns value which is always ignored > fprintf umask putenv > setgid setuid time > signal strcpy unlink > fflush printf sprintf > strcat sleep fputs >(The sum total of lint warnings from a program *under >development*. I can tell you why *each* of these is there. And I >can tell you, also, which I'm not going to get rid of in the >production version.) Anybody maintaining this code will have to determine why EACH warning occurs and whether or not it represents a potential problem. For example, when *printf() and fflush() report errors, is it really safe to not detect that? In most production applications, it would be a serious mistake to ignore an output error. Similar things could be said about most of these functions (the str*() family being the exception, since they never report failure). Your code may be perfectly okay, but from years of experience maintaining UNIX system code written by other people, I've found that I cannot afford to ignore such "lint" warnings. If, on the other hand, I've taken the trouble to completely inspect and de-lint a chunk of software, then at any future date when "lint" shows up in it I know there is a real problem. In the long run it saves me time. P.S. I don't think you should take counterarguments so personally. As I said, if your approach works for you, more power to you. Mine certainly works better for me.
dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) (11/28/89)
In article <316@voa3.UUCP> ck@voa3.UUCP (Chris Kern) writes: >But what about a standard library function whose value I >(perhaps recklessly) wish to ignore? Should I cast the function >call to void, or am I just indulging in the trivial luxury of >silencing lint? I will crudely divide standard library functions into two groups, based on their return value: 1. Those that return a status value 2. Those that return data Many though not all of the standard I/O functions are in the first category. Most of the string functions are in the second category. (There are some that return one or the other, e.g., returning either data or EOF. Handle with care.) The return value from category 2 functions can usually be safely cast to void. This is quite common with strcpy, strcat, and similar functions that return a pointer whose value you already have elsewhere. You are mainly accommodating the fact that what you needed was a procedure but all you had was a function, and telling lint not to remind you of this. The return value from category 1 functions should be cast to void only when you don't need the status value. This takes more thought than with category 2 functions. Possibilities are: a. You were reading from or writing to an I/O stream, and you will check for an error later (e.g. with ferror). Most commonly you will do a series of reads or writes without checking for an error each time, and then finally test with ferror. b. There isn't much you can do about the error now, so you just give up. Very few people, for example, bother to check for an error occurring on stderr after they have used fprintf to print an error message to it. c. You *know* what the status code is going to be, so you don't check it. This usually arises out of careful analysis of your program, or total recklessness. In either case, be very suspicious. I can't think of many standard library functions that return a predictable status code. d. Anything else that I missed. Rahul Dhesi <dhesi%cirrusl@oliveb.ATC.olivetti.com> UUCP: oliveb!cirrusl!dhesi
flaps@dgp.toronto.edu (Alan J Rosenthal) (11/29/89)
dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) writes: >I will crudely divide standard library functions into two groups, based >on their return value: > >1. Those that return a status value >2. Those that return data ... >The return value from category 2 functions can usually be safely cast >to void... I don't think this is a very good taxonomy. You should distinguish functions that return interesting data from functions that return boring data. Functions like strcpy() that return boring data can be safely cast to void. Functions like atof() that return interesting data cannot. ajr -- "Learning algorithms from Knuth is almost as bad as learning physics from Newton in the Latin original." -- Jeffrey Kegler
bill@twwells.com (T. William Wells) (12/08/89)
In article <11680@smoke.BRL.MIL> gwyn@smoke.BRL.MIL (Doug Gwyn) writes: : In article <1989Nov23.233403.2841@twwells.com> bill@twwells.com (T. William Wells) writes: : >function returns value which is always ignored : > fprintf umask putenv : > setgid setuid time : > signal strcpy unlink : > fflush printf sprintf : > strcat sleep fputs : >(The sum total of lint warnings from a program *under : >development*. I can tell you why *each* of these is there. And I : >can tell you, also, which I'm not going to get rid of in the : >production version.) : : Anybody maintaining this code will have to determine why EACH warning : occurs and whether or not it represents a potential problem. For : example, when *printf() and fflush() report errors, is it really safe : to not detect that? In most production applications, it would be a : serious mistake to ignore an output error. In this case, each output function is either an output to stderr, debugging output, or later checked with ferror. There are similar reasons for most of the other functions. The ones where some reason does not exist will eventually go away. The primary reason that I ignore the function return value messages is that I believe that adding the extra casts detracts from readability. Between that, and the minor irritation of putting in all the casts, I decided that, in many cases, it is not worth it to eliminate those messages. It is also worth noting that, for example, casting the one sleep call (in this bit of code) to void does not mean that the reader of the code is spared the necessity of figuring out why the result of the sleep is not used. For that, a comment is necessary. In which case, the cast becomes redundant. (And actually, in this case, the comment isn't even necessary. I'm just using it in a busy loop [argh!] and that a shortened delay is mostly harmless is obvious.) The best argument I've heard for always eliminating them is that, if someone has to add a use of a function in this list, he needs to be more careful about what he does with return values than he would otherwise. (I.e., he can't rely on lint catching him if he forgets to use a return value he should have.) The other argument, that these messages might indicate a problem in the code, I find less valuable. This is because I always do code reviews. When I do a code review, I have to check just as carefully a cast function as I do one whose return value is ignored. Accordingly, the cast does not make my job easier. The person who would benefit is someone who has to take my code and figure out what I've done. Adding the cast would tell him that *I* think that the function result should be ignored; I don't know about you, but when I see such in other's code, I tend to not take their word for it unless the reasons are obvious, in which case the cast doesn't help much. It is a trade-off. I'm on the side of permitting a short list of these functions. I wouldn't have a conniption if I were required to eliminate them all, but I don't see a compelling reason to. : Your code may be perfectly okay, but from years of experience : maintaining UNIX system code written by other people, I've found : that I cannot afford to ignore such "lint" warnings. If, on the : other hand, I've taken the trouble to completely inspect and de-lint : a chunk of software, then at any future date when "lint" shows up in : it I know there is a real problem. In the long run it saves me time. Generally this is true. I make only two exceptions to the rule. The first is for the function return value which is never used, the second is for things that it is difficult or wrong to make lint shut up about. (For that latter, consider bugs in lint.) I'm ambivalent on what to do with things that take #ifdef lint to make lint shut up. Doing it for malloc is one thing, one can arrange that all the checking that should be done gets done. But using #ifdef lint just to eliminate a bit of code that lint won't otherwise shut up about strikes me as dangerous. On the flip side, leaving around random lint warnings isn't good either. But the only solution seems to be to recode, often in ways that causes other problems. : P.S. I don't think you should take counterarguments so personally. : As I said, if your approach works for you, more power to you. Mine : certainly works better for me. If it had been a counterargument, I wouldn't have taken it personally. I'm sick up to here with ad hominems where arguments belong. Hence my nasty response to him. --- Bill { uunet | novavax | ankh | sunvice } !twwells!bill bill@twwells.com