[comp.lang.c] Undefined structures

jim@newmedia.UUCP (Jim Beveridge) (02/05/91)

Microsoft C compiles the following program with no errors:

	extern int callvw(struct _vw_package *pack);

	main()
		{
		}

I find this rather amazing considering that "struct _vw_package"
is undefined.

If I compile the program with gcc 1.37 under SunOS, I get this error:

t.c:1: warning: `struct _vw_package' declared inside parameter list
t.c:1: warning: its scope is only this definition or declaration,
t.c:1: warning: which is probably not what you want.

This would seem to imply that MSC v6 _might_ be doing the right thing
by defining the structure for just inside the prototype.

If I make the declaration, "struct junk *g;"  after the extern
above,  it compiles correctly even though "struct junk" doesn't
exist.

What exactly is going on here:

	What is the scope of these declarations?
	How are these references being resolved?
	What is proper compiler behavior?

		Thanks,
		 Jim

gwyn@smoke.brl.mil (Doug Gwyn) (02/05/91)

In article <442@newmedia.UUCP> jim@newmedia.UUCP (Jim Beveridge) writes:
>If I make the declaration, "struct junk *g;"  after the extern above,
>it compiles correctly even though "struct junk" doesn't exist.

struct junk *g; declares that g is a pointer to a struct tagged "junk"
(that in this case has not yet had its members declared).  This is one
instance of an "incomplete type".  If the program is to make any use of
the type that requires a complete type, e.g. sizeof(*g), then there
must be another declaration that completes the type before it is used.
If the type is never needed for anything, it need not be completed.

There are two other loosely related points:  The standard seems to say
that all structure/union/enum tags and typedef names used in prototype
parameter declarations have prototype scope, but I think that is not
the intention; rather if a declarator was included it is just the
identifier in the declarator portion that has prototype scope, not one
in the type-specifier portion.  (This would be worth getting a formal
interpretation ruling on.)  The other point is that all pointers to
struct turn out to have to have similar representations (at least so
many of us think), so a pointer to any kind of struct would be good
enough for the compiler and it may not notice that you never declare
what the particular kind you actually referred to actually looks like.

henry@zoo.toronto.edu (Henry Spencer) (02/05/91)

In article <442@newmedia.UUCP> jim@newmedia.UUCP (Jim Beveridge) writes:
>	extern int callvw(struct _vw_package *pack);
>
>I find this rather amazing considering that "struct _vw_package"
>is undefined.

Not an issue.  It is an "incomplete type", so there are vague restrictions
on doing certain things with it, but declaring pointers to incomplete types
is perfectly legal.  The intuitive rule is that you can do anything that
doesn't require knowing the size or contents of the struct (unfortunately,
ANSI C phrases it in about that way, but doesn't bother saying precisely
where the size is needed).

This esentially means that all pointers to struct have to use the same
representation.

What GCC is trying to warn you about is that this incomplete type exists
only within that one declaration, meaning that there is no way to declare
anything else with the same type.
-- 
"Maybe we should tell the truth?"      | Henry Spencer at U of Toronto Zoology
"Surely we aren't that desperate yet." |  henry@zoo.toronto.edu   utzoo!henry