🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c
Article #3166

struct* mention before declaration/definition

#3166
From: "Don McCrady"
Date: Fri, 21 Jun 1991 20:06
57 lines
2808 bytes
> 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;
Technical Details
Message-ID: <9106212027.AA12515@ucbvax.Berkeley.EDU>
Path: arc1-ca.pugleaf.net!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

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!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