Mail Archives: djgpp-workers/2001/06/09/07:44:38
> From: Martin Str|mberg <ams AT ludd DOT luth DOT se>
> Date: Sat, 9 Jun 2001 11:16:06 +0200 (MEST)
> > >
> > > make -C ansi/stdio
> > > gcc ... -c doprnt.c
> > > cc1.exe: warnings being treated as errors
> > > doprnt.c: In function `_doprnt':
> > > doprnt.c:167: warning: passing arg 1 of `todigit' with different width due to prototype
> >
> > Change `todigit' (near the beginning of doprnt.c) to accept an int
> > instead of a char, and the warning will go away.
>
> Yes, but *fmt is a char and todigit expects a char. The warning
> doesn't make sense to me.
The traditional definition of the C language was that any char or
short arguments are promoted to int when they are passed to functions.
(This is consistent with what happens in expressions.) Likewise,
float's are promoted to double's (that's why you use %f in fprintf
with both float and double variables.) This is how it was since day
one in C, and there was rejoycing everywhere.
Then along came ANSI Standard, a.k.a. C89, with its language purists
who said ``What? can't I declare a function to accept a short or a
float?? Over my dead body!!'' So ANSI C allowed function prototypes
to declare char, short, or float arguments.
This makes code compiled with and without a prototype behave
differently; omit a prototype or forget to include a header, and your
code breaks. There's also a subtle point of variable-argument
functions such as fprintf and anything else that uses va_arg: the
arguments to those functions are _still_ subject to traditional C
promotions. So if you change a function which has a char argument
into a vararg function, it also breaks.
> And you seem to say *fmt is an int?
No. *fmt is a char, and it will be promoted to int when a call to
`todigit' is made.
> > Basically, this warning alerts you to any function whose prototype
> > modifies the default promotion of arguments. This flags functions
> > whose prototypes include char, short, and float arguments. IMHO,
> > these practices are unsafe and should be avoided.
>
> They are? Isn't that what prototypes are for?
See above.
In addition to the reasons I listed, there's one more: the traditional
C promotion rules were designed with efficiency in mind (Thompson and
Ritchie knew what they were doing). Look at the code generated by the
compiler in both cases, and I think you'll see.
- Raw text -