Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!pacific.mps.ohio-state.edu!linac!att!ucbvax!torolab6.vnet.ibm.com!mccrady From: mccrady@torolab6.vnet.ibm.com ("Don McCrady") Newsgroups: comp.std.c Subject: struct* mention before declaration/definition Message-ID: <9106212027.AA12515@ucbvax.Berkeley.EDU> Date: 21 Jun 91 20:06:43 GMT Sender: daemon@ucbvax.BERKELEY.EDU Lines: 57 > From: msw@unix.cis.pitt.edu (Matt S Wartell) > > /* declaration of function */ > void add_version(int a, struct B *b); /* 1 */ > > /* definition of structure */ > struct B { /* 2 */ > ... > }; > > /* definition of function */ > void add_version(int a, struct B *b) /* 3 */ > { > ... > } > > When the compiler gets to the function definition, it complains of a > type mismatch in parameter b. It is our impression that the compiler > should produce an error at the function _declaration_ ... A struct tag can be introduced before the structure has been defined, and is called an incomplete type. Thus, the declaration of function add_version() is entirely legal (but not too useful, as I'm about to explain). I've marked up your example with /* n */ to refer to specific lines. You should be getting an error message on or about the function definition (/* 3 */) because of C's scoping rules for function declarations. On the function declaration (/* 1 */), the left parenthesis that begins the parameter list opens a new scope. The following identifiers are local to that scope: a, B, and b. When the right parenthesis that ends the parameter list is seen, this scope closes, and all these identifiers disappear, including B. Note that B was an incomplete type that can never be completed, since nobody from an outside scope can peek inside this one. On /* 2 */, a new identifier B is introduced. Since we're at a different scope, this is an entirely different B than the one we introduced at /* 1 */. Just to show the distinction, I'll call this new identifier B' (B-prime). On /* 3 */, the compiler should notice that the definition of function add_version() does not match the original prototype. Why? Because the second parameter is different: the function declaration declared its second parameter to be a struct B *, and the function definition declared its second parameter to be a struct B' *. Not compatible, hence the error message. The real problem, as you mentioned, is that the declarations are out of order. If you had put the declaration for struct B before everything else, all occurrences of struct B would have resolved to the same identifier. ++don;