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