Pointers to Incomplete Types in Prototypes

Norman Diamond diamond at jit533.swstokyo.dec.com
Tue May 7 13:09:25 AEST 1991


In article <683g+p#@rpi.edu> xor at aix01.aix.rpi.edu (Joseph Schwartz) writes:
>The paragraph in question is 3.1.2.1, lines 32-37:
>"If the declarator or type specifier that declares the identifier appears
                    -----------------
>within the list of parameter declarations in a function prototype (not
>part of a function definition), the identifier has FUNCTION PROTOTYPE
>SCOPE [emphasis theirs], which terminates at the end of the function
>declarator.  If an outer declaration of a lexically identical identifier
>exists in the same name space, it is hidden until the current scope
>terminates, after which it again becomes visible."
> 
>As I said earlier, I believe this applies to the identifier "stool" in:
>     extern void foo(struct bar *stool);
>I could also believe that it applies to complete structure declarations,
>as in:
>     extern void foo(struct bar { int a; int b; } *);
>But I still have a hard time believing that it applies to struct bar in:
>     extern void foo(struct bar *);

It certainly does.  It says "type specifier" with no exceptions.

>Making bar have local scope in this case is of questionable usefulness,

I agree, but that's not the issue any more.

>and it would appear to break code that existed before the Standard.

This also isn't the issue at the moment, but just how much PROTOTYPED code
do you think existed before the Standard?

>But let's assume that the correct interpretation of the Standard is to
>give struct bar local scope in my last example above.  Then why does this:
>      struct bar;
>      extern void foo(struct bar *);
>solve the scoping problems?  According to the paragraph that I quoted above,
>the vacuous declaration of struct bar is HIDDEN inside the prototype.

No.  A new declaration of "bar" would hide the outer declared "bar".
The Standard plays a dirty trick in section 3.5.2.1, page 61 lines 23-34:
"The presence of a struct-declaration-list in a struct-or-union-specifier
declares a new type, within a translation unit."
(Hmm, this doesn't exactly say that this declares the TAG, but presumably
an interpretation ruling would say so.)
And then section 3.5.2.3, page 63 lines 31-35, give the famous case of a
vacuous declaration (which can break old code).
Your type-name of "struct bar *" does not meet either of these criteria,
so it does not declare a new type.

Aside -- something troubles me about the answer that I have just given.
A declaration must declare at least a declarator, a tag, or the members
of an enumeration, but a type-name need not do so.  Furthermore, a
type-name does not have the form described in 3.5.2.3, page 63 line 32:
" struct-or-union identifier ; "
because a type-name declaration in a prototype doesn't have a semicolon.
I'm not sure why I'm troubled; perhaps another logician can help out.
--
Norman Diamond       diamond at tkov50.enet.dec.com
If this were the company's opinion, I wouldn't be allowed to post it.



More information about the Comp.std.c mailing list