Date: Sat, 09 Jun 2001 14:43:05 +0300 From: "Eli Zaretskii" Sender: halo1 AT zahav DOT net DOT il To: Martin Str|mberg Message-Id: <9743-Sat09Jun2001144304+0300-eliz@is.elta.co.il> X-Mailer: Emacs 20.6 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.9 CC: djgpp-workers AT delorie DOT com In-reply-to: <200106090916.LAA26228@mother.ludd.luth.se> (message from Martin Str|mberg on Sat, 9 Jun 2001 11:16:06 +0200 (MEST)) Subject: Re: Compiler options for djdev build References: <200106090916 DOT LAA26228 AT mother DOT ludd DOT luth DOT se> Reply-To: djgpp-workers AT delorie DOT com Errors-To: nobody AT delorie DOT com X-Mailing-List: djgpp-workers AT delorie DOT com X-Unsubscribes-To: listserv AT delorie DOT com Precedence: bulk > From: Martin Str|mberg > 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.