[comp.lang.c] ansi weirdness

andrew@alice.UUCP (Andrew Hume) (09/07/90)

the following C fragment fails with a strict ANSI compiler (lcc)
but compiles with sloppy ones (e.g. gcc):

	typedef int (*fn)(struct x *);
	extern int fn1(struct x *);
	extern fn *fp = fn1;

the ostensible reason is that the two struct x's are different
(or at least, have different scopes).
this may be technically correct but is just wrong.
can anyone explain why anyone would want this batshit behaviour?

andrew@alice.UUCP (Andrew Hume) (09/09/90)

In article <11305@alice.UUCP>, andrew@alice.UUCP (Andrew Hume) writes:
~ 
~ the following C fragment fails with a strict ANSI compiler (lcc)
~ but compiles with sloppy ones (e.g. gcc):
~ 
~ 	typedef int (*fn)(struct x *);
~ 	extern int fn1(struct x *);
~ 	extern fn *fp = fn1;
~ 
~ the ostensible reason is that the two struct x's are different
~ (or at least, have different scopes).
~ this may be technically correct but is just wrong.
~ can anyone explain why anyone would want this batshit behaviour?

let me correct an error and clarify; the fragment contains a bug - it should be

 	typedef int (*fn)(struct x *);
 	extern int fn1(struct x *);
 	extern fn fp = fn1;

i understand technically (i think) what is going on.
the first line introduces a type struct x which goes away
at the end of the prototype and can never be used again.
my question is why didn't ANSI do what C++ does here and export
the type up to file scope?


andrew@research.att.com

vu0310@bingvaxu.cc.binghamton.edu (R. Kym Horsell) (09/10/90)

In article <11305@alice.UUCP> andrew@alice.UUCP (Andrew Hume) writes:
[]
>	typedef int (*fn)(struct x *);
>	extern int fn1(struct x *);
>	extern fn *fp = fn1;
[Why does the (ANSII) compiler say struct's are different]?

Don't ask _why_ just put ``struct x;'' in front.

-Kym Horsell

andrew@alice.UUCP (Andrew Hume) (09/10/90)

just in case i miscommunicated, when i said sloppy ansi c
compilers (gcc), i referred to its default behaviour.
otherwise, its warning messages seem exemplary:

xx.c:1: warning: `struct x' declared inside parameter list
xx.c:1: warning: its scope is only this definition or declaration,
xx.c:1: warning: which is probably not what you want.
xx.c:2: warning: `struct x' declared inside parameter list
xx.c:3: warning: `fp' initialized and declared `extern'
xx.c:3: warning: initialization between incompatible pointer types

sorry for any unintended denigration of GNU's gcc.

scjones@thor.UUCP (Larry Jones) (09/10/90)

In article <11312@alice.UUCP>, andrew@alice.UUCP (Andrew Hume) writes:
>  	typedef int (*fn)(struct x *);
>  	extern int fn1(struct x *);
>  	extern fn fp = fn1;
> i understand technically (i think) what is going on.
> the first line introduces a type struct x which goes away
> at the end of the prototype and can never be used again.
> my question is why didn't ANSI do what C++ does here and export
> the type up to file scope?

Because the committee got tired of C being an almost block
structured language -- the exceptions are very difficult to
describe concisely and completely -- so they tried to tighten
up the structuring wherever possible.  Since prototypes were
a committee invention, they got tight scoping rules.  Making
exceptions to the rules when it's convenient to do so may
seem like a good idea at the time, but it just causes a great
deal of pain and aggravation when you have to explain just
exactly when the exceptions occur and what they do.
----
Larry Jones                         UUCP: uunet!sdrc!thor!scjones
SDRC                                      scjones@thor.UUCP
2000 Eastman Dr.                    BIX:  ltl
Milford, OH  45150-2789             AT&T: (513) 576-2070
You can never really enjoy Sundays because in the back of your
mind you know you have to go to school the next day. -- Calvin

peter@dbaccess.com (Peter A. Castro) (09/11/90)

in article <11305@alice.UUCP>, andrew@alice.UUCP (Andrew Hume) says:
> 
> 
> the following C fragment fails with a strict ANSI compiler (lcc)
> but compiles with sloppy ones (e.g. gcc):
> 
> 	typedef int (*fn)(struct x *);
> 	extern int fn1(struct x *);
> 	extern fn *fp = fn1;
                  ^^^
	don't you mean "extern fn fp = fn1;"  ?
> 
> the ostensible reason is that the two struct x's are different
> (or at least, have different scopes).
> this may be technically correct but is just wrong.
> can anyone explain why anyone would want this batshit behaviour?

  I tried running your example through two ANSI compilers (RS/6000 XLC,
  and Amiga Aztec C 5.0) and on the second extern got a message:
  "Illegal initialization between types POINTER and POINTER."
  However, to me your extern looks like you are making fp a pointer to
  a pointer to a function.  In that case, the compiler is correct in that
  a pointer to a function is not the same as a pointer to a pointer to
  a function.  However, a compiler that is less stringent will let it
  pass because it resolves that pointers are the same base type.
  I guess I have to ask what was your intent.

-- 
Peter A. Castro                   INTERNET: peter@dbaccess.com        // //|
c/o DB/Access Inc.                UUCP: {uunet,mips}!troi!peter      // //||
2900 Gordon Avenue, Suite 101     FAX: (408) 735-0328            \\ // //-||-
Santa Clara, CA 95051             TEL: (408) 735-7545             \// //  ||