[comp.sys.sgi] 3.3 C Weirdness

pepke@gw.scri.fsu.edu (Eric Pepke) (09/24/90)

There is a weirdness in the C that comes with 3.3 when the -prototypes 
argument is supplied.

I like to put prototypes in the .h file associated with each .c file, and 
then use old style definitions in the .c file.  That way, if I want to 
compile on a 3030, I just hack out the prototypes and it compiles fine.

With the new C, however, I sometimes get some odd error messages of the 
form

old/new style declaration and definition of <function name> argument  <#> 
mismatch: change the definition to the new (function prototype) style.

As far as I can tell, this does not in any way affect code generation; 
everything compiles fine.  It only seems to occur when the argument type 
in the prototype is a different size from the type it is promoted to when 
normally passed on the stack.  

For example, an int is the same size as a long, and a short is shorter.  
Integer arguments are normally passed as ints, so shorts and chars are 
ordinarily promoted to ints when passed.

This fragment would compile fine:

void bork(int);

void bork(i)
int i;
{
}

These would fail:

void face(char);

void face(c)
char c;
{
}

void fat(short);

void fat(s)
short s;
{
}

However, both of these would work:

void face(char c)
{
}

void fat(short s)
{
}

This behavior puzzles me, because by the time the parser gets to the open 
bracket, which is where the error is detected, it has enough semantic 
information to do the right thing no matter whether new- or old-style 
definitions are used.  Selectively to reject old-style definitions seems 
needlessly purist.

Does there exist a fix or workaround for this?  I would call the hotline, 
were it not for the difficulty in explaining things like this in detail 
over the phone.

Eric Pepke                                    INTERNET: pepke@gw.scri.fsu.edu
Supercomputer Computations Research Institute MFENET:   pepke@fsu
Florida State University                      SPAN:     scri::pepke
Tallahassee, FL 32306-4052                    BITNET:   pepke@fsu

Disclaimer: My employers seldom even LISTEN to my opinions.
Meta-disclaimer: Any society that needs disclaimers has too many lawyers.

davea@quasar.wpd.sgi.com (David B.Anderson) (09/25/90)

In article <761@sun13.scri.fsu.edu> pepke@gw.scri.fsu.edu (Eric Pepke) writes:
>There is a weirdness in the C that comes with 3.3 when the -prototypes 
>argument is supplied.
>
>I like to put prototypes in the .h file associated with each .c file, and 
>then use old style definitions in the .c file.  That way, if I want to 
>compile on a 3030, I just hack out the prototypes and it compiles fine.
>
>With the new C, however, I sometimes get some odd error messages of the 
>form
>
>old/new style declaration and definition of <function name> argument  <#> 
>mismatch: change the definition to the new (function prototype) style.
>
>As far as I can tell, this does not in any way affect code generation; 

This message means that you are doing something that violates the
ANSI C rule that, when mixing a prototype with an old-style definition:
	``the type of each parameter shall be compatible with the
	  type that results from the appliation of the default
	argument promotions.''
So that would mean declaring the argument as int, not char (everywhere).

(This compiler is not an ANSI C compiler but it does enforce some basic
ANSI rules for function prototypes.)

So:
	int x(char);
	int x(z) char z; { }
is an error,while
	int x(char);
	int x(char z) { }
is correct.

The compiler is complaining because a) the usage in error will generate
code that will not work for some (non-sgi) machines for char, short,
unsigned char, unsigned short.   b) the resulting code will defininitely
not work on our machines if one has
	int x(float);
	int x(y) float y; { }
since  any call seeing the prototype will pass a float, while the function
definition expects  a double (after K&R type rewriting to double).

The compiler is just trying to keep you from writing non-portable/erroneous
code.

It's for your own good :-).

Hope this helps.
[ David B. Anderson  Silicon Graphics  (415)335-1548  davea@sgi.com ]
[``What can go wrong?''                          --Calvin and Hobbes]

pepke@gw.scri.fsu.edu (Eric Pepke) (09/26/90)

In article <70109@sgi.sgi.com> davea@quasar.wpd.sgi.com (David B.Anderson) 
writes:
> b) the resulting code will defininitely
> not work on our machines if one has
>         int x(float);
>         int x(y) float y; { }

Strange.  I have 15,000 lines of code with stuff like this out the wazoo, 
and it seems to work fine.  Of course, the prototype is visible when the 
function is defined.  Perhaps the compiler does the sensible thing in 
spite of whining about it.

Eric Pepke                                    INTERNET: pepke@gw.scri.fsu.edu
Supercomputer Computations Research Institute MFENET:   pepke@fsu
Florida State University                      SPAN:     scri::pepke
Tallahassee, FL 32306-4052                    BITNET:   pepke@fsu

Disclaimer: My employers seldom even LISTEN to my opinions.
Meta-disclaimer: Any society that needs disclaimers has too many lawyers.

davea@quasar.wpd.sgi.com (David B.Anderson) (09/26/90)

In article <803@sun13.scri.fsu.edu> pepke@gw.scri.fsu.edu (Eric Pepke) writes:
>In article <70109@sgi.sgi.com> davea@quasar.wpd.sgi.com (David B.Anderson) 
>writes:
>> b) the resulting code will defininitely
>> not work on our machines if one has
>>         int x(float);
>>         int x(y) float y; { }
>
>Strange.  I have 15,000 lines of code with stuff like this out the wazoo, 
>and it seems to work fine.  Of course, the prototype is visible when the 
>function is defined.  Perhaps the compiler does the sensible thing in 
>spite of whining about it.

Yes, you are quite right.  My mistake.  However it's still not
a good idea to do this, since it is a clear violation of the ANSI C standard.

{Apologies for the earlier misinformation....}
[ David B. Anderson  Silicon Graphics  (415)335-1548  davea@sgi.com ]
[``What can go wrong?''                          --Calvin and Hobbes]