Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!samsung!xylogics!transfer!lectroid!charis!wmm From: wmm@charis.UUCP (William M. Miller) Newsgroups: comp.std.c Subject: Re: Scope of incomplete types Message-ID: <1990Sep9.194037.346@charis.UUCP> Date: 9 Sep 90 19:40:37 GMT References: <1990Sep5.191221.5118@charis.UUCP> <13765@smoke.BRL.MIL> Reply-To: wmmiller@cup.portal.com Organization: none Lines: 96 In article <13765@smoke.BRL.MIL> gwyn@smoke.BRL.MIL (Doug Gwyn) writes: > In article <1990Sep5.191221.5118@charis.UUCP> wmmiller@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@cup.portal.com BIX: wmiller CI$: 72105,1744