------- Comment #12 from raeburn at raeburn dot org  2007-08-29 21:51 -------
Subject: Re:  Error in compiling when there is a function with a char parameter
called before its declaration with inline parameters.

On Aug 29, 2007, at 13:39, andreagrassi at sogeasoft dot com wrote:
> I accept the answer to gave me but then also the definition of
>
>     a(a)
>        char a;
>     {
>     ...
>
> should be invalid. I don't understand why if I define
>
>     a(char a)
>     {
>     ...
>
> the compiler take a as "char" and don't match with promoted type  
> giving me
> an error whereas the other way the compiler promotes the "char a"  
> to "int"
> ALSO IN THE DEFINITION of the function !!

It would seem to make sense, wouldn't it?  But that's not how the C  
standard was defined.  It does cause confusion, but I guess the  
benefit of letting "new-style" code be optimized better (e.g., you  
can read a byte from memory and stuff it in the argument list,  
without having to do the signed or unsigned widening to full "int",  
or pass a "float" using 4 bytes on the stack instead of widening it  
to an 8-byte "double") while leaving the meaning of "old-style" code  
unchanged (old 1970s and 1980s compilers would always do the "default  
promotions", even if it slowed down the code a little) was deemed to  
be worth it.  I wasn't there, and can't read the minds of the people  
on the committee, but it's a fait accompli at this point.

Note too that in the 1999 version of the standard, the ability to  
write the "old-style" code is described an "obsolescent feature", and  
the general direction the standards are moving in seems to suggest  
that you should (1) always include a prototype declaration before  
calling a function (or include the relevant header for standard C  
functions), and (2) always use the prototype-style function  
definitions instead of the older style.  Having a prototype  
declaration in scope before using a function is good practice,  
anyways, because it lets the compiler do better type-checking of your  
function call, even if the function definition isn't in the same file.

> Why in summary
>
>     a(a)
>        char a;    // => promoted to int
>     {
>     ...
>
> whereas
>
>     a(char a)    // =>remains char
>     {
>     ...
>
> The two manner defines the SAME THING (even if in 2 different  
> forms) and
> MUST be treated identically

The C language specification says no, they're actually not the same.   
It causes some confusion when converting old C code to use prototype  
declarations and definitions, because you might think you could just  
move the argument declaration up without changing the semantics, but  
it does change them subtly.

> Then, finishing, I don't understand because you must promote a  
> parameter
> EXPLICITLY rapresented by a char-constant as 'A' or by a variable  
> previously
> declared as char, or why, once promoted, you cannot re-correct the  
> signature
> !! The definition should override the implicitly signature .
> I know it's from always so, but this is a twist of the logic of the
> language.

Actually, that's another funny point of C... and in fact it's an area  
where C and C++ are different.  Character constants like 'A' are  
actually considered to have type "int" in C, not type "char"!  I have  
no idea what the logic was behind that (probably it's what 1970s-80s  
compilers did), but once again, it was decided years ago and that's  
the way it is.

Go ahead and try something like

   printf("%d\n", sizeof('a'));

... the size isn't 1 in C, it's the size of an int.

C++, on the other hand, treats 'A' as a "char" constant.  It's  
probably a lot more important to distinguish "char" from "int" in C++  
where you might be doing function overloading or template  
instantiation based on the type.

Ken


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33219

Reply via email to