New 'n' Improved comp.lang.c FAQ List

Paul Dow CRI-UK paul at sequoia.cray.com
Thu Apr 4 20:24:53 AEST 1991


Will this never end.....   Here's my three ha'pence....

In article <1991Apr4.024300.19969 at garfield.cs.mun.ca>, matthew1 at garfield.cs.mun.ca (Matthew J. Newhook) writes:
|> bls at u02.svl.cdc.com (Brian Scearce) writes:
|> 
|> >grover at 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 <math.h>
|> 
|> 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]



More information about the Comp.lang.c mailing list