Path: utzoo!news-server.csri.toronto.edu!rutgers!sun-barr!lll-winken!uunet!mcsun!ukc!acorn!john From: john@acorn.co.uk (John Bowler) Newsgroups: comp.sys.acorn Subject: Re: Another query about the behaviour of the C compiler (version 3.00) Keywords: C, Acorn C compiler Message-ID: <5713@acorn.co.uk> Date: 11 Mar 91 10:37:28 GMT References: <1925@tharr.UUCP> Organization: Acorn Computers Ltd, Cambridge, UK Lines: 82 In article <1925@tharr.UUCP> gtoal@tharr.UUCP (Graham Toal) writes: >:"c.rl", line 45: Error: 'return': implicit cast of pointer to non-equal pointer >: >:Illegal address (e.g. wildly outside array bounds) > >This is the only bug I've found in NorCroft, and it only happens with >a wrong program: in Ansi, if you give a spec for a procedure which has a >struct as a parameter, and then actually declare the struct type *after* >the declaration, - when you come to the body of the procedure you will >get a type check error on the struct. The solution is to move the struct >type declaration to above the external procedure/forward declarations. > >The annoying thing is that this was legal in k&r, so many existing >programs do it :-( It shouldn't ever occur in a pre-ANSI program; because K&R did not support function prototypes it wasn't possible to do this: Definitions in scope ==================== void foo( struct foo1 x /* Definition foo1A */ foo1A ); struct foo1 { int y; }; /* Definition foo1B */ foo1B struct foo2 { int z; }; /* Definition foo2A */ foo1B foo2A foo1B foo2A void foo( foo1B foo2A struct foo1 x /* == foo1B */ foo1B foo2A ) { foo1B foo2A struct foo2 { double a; } b; /* foo2B */ foo1B (foo2A) foo2B foo1B (foo2A) foo2B ... foo1B (foo2A) foo2B } foo1B foo2A foo1A disappears after the closing ) of the foo function declaration, just as foo2A disappears after the closing }. You could do the second with the K&R implementations which I know (ie have two structs foo2, the second (type definition) obscuring the first). You couldn't do the first, because K&R didn't permit declaration of function arguments. Purists might observe that the real reason is that C permits implicit type definitions inside declarations. I can't remember if the code:- void foo() { struct foo1 { int y; } x; /* Definition A */ .... } void bar() { struct foo1 z; /* Programmer means definition A */ .... } was actually legal with pcc, but the chances of finding such a thing in existing K&R code must be very small - writing the code ``correctly'' is so much easier and more obvious. (Think what happens in the above code if someone innocently adds a ``struct foo1'' definition prior to function foo()). Adding function argument prototypes to pre-ANSI code often throws up this problem. The easy workround is:- struct foo1; /* Add this line */ void foo( struct foo1 x ); If you don't like the warning the compiler generates as a result :-( use the following:- typedef struct foo1 XX_foo1_dummy; void foo ( struct foo1 x ); John Bowler (jbowler@acorn.co.uk)