Scope of incomplete types

William M. Miller wmm at charis.UUCP
Mon Sep 10 05:40:37 AEST 1990


In article <13765 at smoke.BRL.MIL> gwyn at smoke.BRL.MIL (Doug Gwyn) writes:
> In article <1990Sep5.191221.5118 at charis.UUCP> wmmiller at cup.portal.com writes:
> >                struct X* xp1
> >                {
> >                   struct X* xp2;
> >                   }
>
> Neither of these declares a struct X.  That is a crucial point to
> understand in conjunction with the example from 3.5.2.3 that you cited.
 
What do you mean by "declaring a struct X?"  The exact wording of 3.5.2.3 is
 
        If a type specifier of the form
 
                struct-or-union identifier
 
        occurs prior to the declaration that defines the content, the
        structure of union is an incomplete type.  It declares a tag that
        specifies a type that may be used only when the size of an object of
        the specified type is not needed.
 
When it says "declares a tag that specifies a type," I understood that to be
equivalent to declaring a type "struct X."  If you're drawing a distinction
with the standalone declaration
 
                struct X;
 
I don't see it, since the verbiage for this declaration ("specifies a
structure or union type and declares a tag") seems essentially identical.
If you're simply stating that neither declaration defines the contents,
that's obviously true, but my question essentially boils down to whether
such a defining declaration is needed.
 
Besides, in the example, the issue is not whether a struct X is declared;
the wording is, "if s2 were already declared as a tag in an enclosing
scope," and it's clear that "struct X* p1" *does* declare X as a tag.
 
> >... there doesn't appear to be anything in the Standard to indicate any
> >difference in the way the scope rules apply to incomplete types.
>
> That's correct; visibility of an identifier (scope) is not affected by
> incompleteness of its type.
 
So the tag X from the outer block is visible in the inner block.
 
> >        If the type is to be completed, another declaration of the tag in
> >        the same scope (but not in an enclosed block, which declares a new
> >        type known only within that block) shall define the conte7t.
>
> Yes, basically one of the interesting things X3J11 figured out at the
> first interpretation-phase meeting was that the standard insists that
> type information is not propagated outward from a block.  That has all
> sorts of subtle ramifications, fortunately not affecting programmers
> who use sensible coding style in the first place.
 
I'm sorry to be obtuse, but I couldn't determine the "bottom line" in your
posting.  Let me give an example and a few possible interpretations, and
perhaps you can tell me which of them is right and why (or give another
interpretation I hadn't thought of).
 
        struct X* p1;
        void f() {
           struct X* p2;
           p2 = p1;             /* A */
           }
        struct X { int i; };    /* B */
 
INTERPRETATION 1: This is a legal compilation unit.  p1 and p2 have the same
type, so assignment A is allowed.  Implication: the wording in the Standard
requiring a completing declaration to be in the same block does not apply to
the declaration inside f() because the type was introduced in the outer
scope.  Implication: the wording in the Rationale mentioning a definition is
excessively restrictive.
 
INTERPRETATION 2: This is an illegal compilation unit.  p1 and p2 have
different types, so assignment A is in error.  Implication: the wording
describing the example in the Standard is incorrect; instead of "if s2 were
already declared as a tag in an enclosing scope," it should say something
like "if s2 were declared as the tag of a structure whose contents have
already been defined in an enclosing scope."  Implication: the tags of
incomplete types are *not* visible across scopes.
 
INTERPRETATION 3: This is an illegal compilation unit.  p1 and p2 have the
same type, so assignment A is allowed; however, declaration B violates the
restriction requiring a completing declaration to be in the same scope,
since it completes the declaration in f() as well as the one in the outer
scope.
 
(BTW, I agree fully with the comment about "a sensible coding style."  I'm
not trying to see what I can get away with; as a member of X3J16, I'm trying
to figure out what it would mean for C++ to be compatible with C on this
point.)
 
------------------------------------------------------------------------------
William M. Miller, Glockenspiel, Inc.; P. O. Box 366, Sudbury, MA 01776-0003
wmmiller at cup.portal.com         BIX: wmiller            CI$: 72105,1744



More information about the Comp.std.c mailing list