Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!sdd.hp.com!spool.mu.edu!cs.umn.edu!uc!shamash!timbuk!paul From: paul@sequoia.cray.com (Paul Dow (CRI-UK)) Newsgroups: comp.lang.c Subject: Re: New 'n' Improved comp.lang.c FAQ List Message-ID: <030525.19985@timbuk.cray.com> Date: 4 Apr 91 10:24:53 GMT Article-I.D.: timbuk.030525.19985 References: <910401.0xf001@etiquette.uu.net> <1991Apr1.203024.19679@unlv.edu> <31946@shamash.cdc.com> <1991Apr4.024300.19969@garfield.cs.mun.ca> Reply-To: paul@sequoia.cray.com (Paul Dow (CRI-UK)) Organization: Cray Research, Inc. Lines: 117 Will this never end..... Here's my three ha'pence.... In article <1991Apr4.024300.19969@garfield.cs.mun.ca>, matthew1@garfield.cs.mun.ca (Matthew J. Newhook) writes: |> bls@u02.svl.cdc.com (Brian Scearce) writes: |> |> >grover@big-joe.cs.unlv.edu (Kevin Grover) writes: |> >> Apparently non-obvious April Fool's Day bogus account posts: |> >>> Q: Why doesn't this function work: |> >>> |> >>> itoa(int i) |> >>> { |> >>> char retbuf[5]; /* biggest int: 32769 */ |> >>> sprintf("%d", retbuf, i); |> >>> return retbuf; |> >>> } |> >>> |> |> >> A correct version of this program is: |> >> char *itoa(int i) |> >> { |> >> static char retbuf[5]; /* biggest int: 32769 */ |> >> sprintf(retbuf, "%d", i); |> >> return retbuf; |> >> } |> |> >Almost, but not quite, Mr. Grover. The *really* correct version of this: |> |> > char *itoa(int i) |> > { |> > static char retbuf[5]; /* biggest int: 32768 */ |> > sprintf(retbuf, "%d", i); |> > return retbuf; |> > } |> |> Actually here is a correct (portable) version (assuming that you want to |> keep a static character buffer, and not use a newly malloc'd one each time). |> |> #include |> |> char *itoa(int i) |> { |> static int first = 1; |> static char *s; |> |> if (first) { /* IF FIRST TIME ALLOCATE MEMORY FOR STRING */ |> first = 0; |> s = (char *) |> malloc((long) ceil(log10(pow(2, (double) sizeof(int) * 8))) +1); |> if (!s) { |> fprintf(stderr,"malloc failed\n"); |> exit(1); |> } |> } |> |> sprintf(s, "%d", i); |> return s; |> } |> |> This is portable, 'cause it always assigns the correct value to the size of |> the array, without depending on the sizeof(int) == 2. |> |> Matthew Newhook |> It is easy to say that things are "correct" & "portable". How often have people been flamed in this newsgroup (and others) for that. A lot of people are put of replying to questions for fear of being flamed. Mind you, if the replies were framed as suggestions as opposed to "correct"/"portable" etc, then they would not irritate the "flamer" so much. Anyhow, enough of that sideline, let us look at the last example above and ask a few questions ? Q1) The "*8" I presume is for the numbers of bits in a byte. Are there problems here on a 9 bit machine? I don't have access to any such machines, so I cannot test this out. Q2) Should the first parameter to pow() be a double - the compiler may not support prototypes. Q3) The "+1" appears to be for the terminating NULL character. Has any space being allowed for a leading "-" sign ? Q4) Malloc is being passed a "long" type for the number of bytes. Should this be an unsigned (int) [it is on my SunOS 4.1 system]. Q5) If the malloc fails, then a string is written to stderr. Is this accetable? Is it also acceptable to exit at that point ? This may not be acceptable to some applications which might not support a stderr per se ["stderr" might exist, but is it valid to use it ?]. I have encountered this problem with assrted C libraries on several systems. I have to admit that it is good to see return values checked. Code that ignores return values is the bane of my life. Suggestions: Here are a few things that I would think about. They would not change the functionality, but may be worth considering - depending on ones viewpoint. S1) I would tend to use a NULL/not NULL test for the pointer to determine if the buffer needed to be allocated. S2) It took a bit of thinking about to work out what the malloc((long) ceil(log10(pow(2, (double) sizeof(int) * 8))) +1); was doing. Can this be simplified ? S3) It took me a second or two to work out where the result of the malloc was going. It would have helped me of the malloc line was indented more. Paul. [All disclaimers may be assumed]