Topic: Interactions between . and ::
Author: wmm@fastdial.net
Date: 1999/07/25 Raw View
In article <7n7vve$5bp$1@nnrp1.deja.com>,
fvali@biotrack.com wrote:
>
>> > > > > struct Base {int x;};
> > > > > struct A1 : Base {} ;
> > > > > struct A2 : Base {} ;
> > > > > struct Derived : A1, A2 ;
> > > > >
> > > > > Derived der;
> > > > >
> > > > > is der.A1::x supposed to be legal?
> > > > >
> <snip>
>
> > > class A {int x;};
> > > class B : A {};
> > > class C : A {} ;
> > > class D : B, C {};
> > >
> > > D d;
> > >
> > > d.A::x is ambiguous. Right?
> > >
> <snip>
> > In your first example, the lookup is for the qualified name A1::x;
> > that's found in only one subobject, so there's no ambiguity. In
> > the second example, the qualified name A::x is found in two
> > subobjects, and the name designates a non-static member, so there is
> > an ambiguity.
> >
>
> According to 3.4.3.1:
> Para 1, it is the name after the nested-name-specifier (NNS) of a
> qualified id that is looked up in the scope of the class nominated by
> the NNS.
> So the name that is looked up is always 'x' not A1::x or A::x, and it
is
> looked up in the scope of A1, or A.
As I understand it, this is the definition of qualified name lookup
when the nested-name-specifier nominates a class. 3.4.3.1p1 says,
"the name specified after the nested-name-specifier is looked up in
the scope of the class (10.2)." I.e., the phrases "looking up A::x"
and "looking up x in the scope of A" are synonymous (with the
exceptions mentioned in 3.4.3.1p1, of course).
> (I) In the first example (der.A1::x) A1 is nominated, and 'x' is found
> in one of its base classes 'A1::Base' and according to 10.2 since it
is
> a non-static member declaration from just one sub-object, name lookup
> succeeds. Note as this point name lookup has not been concerned with
> the type of our object expresion (der) which is of type 'Derived' at
> all.
>
> Now 5.2.5 para 2 specifies that in the postfix expression E1.E2,
> where E1 is an object-expression, and E2 is an id-expression (ignoring
> templates for now), E2 must name a member of E1. Non-normative text
> states that look up for names following the '.' is performed as
> specified in 3.4.5, which only really states (as reagards qualified
ids)
> how the lookup of a class or namespace name immediately following the
> '.' is performed.
> So A1 is looked up in the context of der.A1::x and found and it is
also
> found when looked up in the 'Derived' and since they refer to the same
> entity, this step proceeds successfully too.
>
> So it is stated that E2 has to name a member of E1 but how exactly is
> this verified? Is this a separate step from the one labeled (I) above?
It's the same step as I. Only (member) declarations in the classes
determined by the form of the id-expression are considered; if it's
not found, it's not a member.
> Qualified ids are never looked up - i.e. 'A1::x' isn't looked up
> anywhere, since when a qualified-id is used to denote an
id-expression,
> the unqualified id portion of the qualified-id is looked up in the
scope
> of the class or namespace nominated by the nested-name-specifier.
See above. The steps described in 3.4.5p4 are _additional_
requirements on qualified names used in a class member access
expression, not a complete description of the lookup. (In other
words, 3.4.5p4 tells you how to figure out what the nested-name-
specifier means; after you've figured that out, then you use the
normal description of qualified lookup to find the declaration to
which the name refers.)
> If this is a separate step then 'x' is looked up in 'Derived' and
found
> to be ambiguous and thus ill-formed.
>
> Anyways I don't think this is very clear at all.
> If we apply the same steps to d.A::x
> 'A' is found in both scopes and refers to same entity.
> 'x' is looked up in 'A' and found to be unambiguous according to 10.2.
> 'x' is looked up in 'D' and found to be ambiguous.
Not exactly. D has two sub-objects "A". The lookup occurs in A and
finds the non-static data member declaration A::x, and that's
ambiguous according to 10.2p2.
--
William M. Miller, wmm@fastdial.net
Software Emancipation Technology (www.setech.com)
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: wmm@fastdial.net
Date: 1999/07/25 Raw View
In article <7n98c9$hlp$1@nnrp1.deja.com>,
aitken17@my-deja.com wrote:
> > > But what of the following:
> > >
> > > struct A {
> > > int x;
> > > };
> > >
> > > struct E : A {};
> > > struct F : A {};
> > >
> > > F f;
> > >
> > > f.E::A::x;
> > >
> > > I have no idea whether this should be legal,
> >
> > In this case, the nested-name-specifier (where the lookup starts,
> > according to 10.2p1) is E::A, which is an acceptable way of naming
> > the class A. In the context of F, there's only one A, only one
> > A::x, and only one A subobject of F, so the lookup succeeds without
> > ambiguity.
> >
>
> By this analysis, it seems to me,
>
> struct A {int x;};
> struct B : A {};
> struct C : A {};
> struct D : B, C {};
>
> D d;
>
> d.B::A::x should be ambiguous: the nested-name-specifier (where the
> lookup starts, according to 10.2p1) is B::A, which is an acceptable
way
> of naming the class A. In the context of D, there is only one class
A,
> but there are multiple A sub-objects, and two A::x
Your analysis is correct. "B::A" just names a type; the path you
went through in naming the type is irrelevant in determining which
"x" you're talking about. The type is used both in the name lookup
and in the determination of which subobjects of the complete object
you will consider, but how you named the type in the nested-name-
specifier is ignored.
You might want to look at the example in 7.3.3p14, which addresses
the same issue in the context of using-declarations.
> It seems bizarre in the extreme that d.B::x shoudl be okay (this is
how
> things got stated) but d.B::A::x should not.
There's no denying that C++ is sometimes counterintuitive to
everyone.
--
William M. Miller, wmm@fastdial.net
Software Emancipation Technology (www.setech.com)
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: aitken17@my-deja.com
Date: 1999/07/27 Raw View
In article <7nd6i1$lqu$1@nnrp1.deja.com>,
wmm@fastdial.net wrote:
> In article <7n94nt$foo$1@nnrp1.deja.com>,
> aitken17@my-deja.com wrote:
> > > > But
> > > > what of the following:
> > > >
> > > > struct A {
> > > > int x;
> > > > };
> > > >
> > > > struct E : A {};
> > > > struct F : A {};
> > > >
> > > > F f;
> > > >
> > > > f.E::A::x;
> > > >
> > >
> > >
> > > In this case, the nested-name-specifier (where the lookup starts,
> > > according to 10.2p1) is E::A, which is an acceptable way of naming
> > > the class A. In the context of F, there's only one A, only one
> > > A::x, and only one A subobject of F, so the lookup succeeds
without
> > > ambiguity.
> > >
> >
> > Just to be certain I understand. f.E::x would not have been legal
> > because there is no E sub-object of F. Right?
>
> Right.
>
> > I think that where I am having trouble is two fold
> >
> > 1) It is not obvious to me why 10.2 applies here [I am not saying
that
> > it's unreasonable that it should, only that I would expect either
> 3.4.5
> > or 5.2.5 to say something that pointed in that direction]. For
> > qualified identifiers follwing the ., 3.4.5 really only talks about
> the
> > lookup of the class-or-namespace-name immediately following the . .
> > 5.2.5 requires that in E1.E2, E2 be a member of E1's class or one of
> > its base classes, but isn't terribly clear how this membership is to
> be
> > detrmined, but that's about as close as it gets to pointing at 10.2.
>
> 3.4p1 indirects to 10.2 in requiring that "Name lookup shall find an
> unambiguous declaration for the name." 3.4.5p4 only talks about
> the first component of the nested-name-specifier because it's really
> just describing how to interpret a nested-name-specifier in a class
> member access expression; after you've figured out the scope the
> nested-name-specifier nominates, it's just an ordinary qualified
> name lookup, described in 3.4.3.1p1 (which also indirects to 10.2).
> 5.2.5 doesn't say anything about lookup, it's just stating the
> semantics once the names in the expression have been associated with
> declarations by the lookup process.
>
> > 2) I'm not convinced I understand what nested-name-specifiers are
> > intended to mean. In particular, I can't find any text (normative
or
> > otherwise) that gives them semantics. In particular, they aren't
> just
> > qualified names followed by :: --- they nest the wrong way round
> > according to the grammar given in 5.1. Am I reading too much into
> > this feature of the concrete syntax? Am I just missing some text,
> > presumably somwhere in clause 3, or perhaps in 5.1?
>
> I'm not sure what you're looking for here. I think the grammar and
> description in 5.1p7 are pretty good. A class-or-namespace-name
> nominates a scope that is then used to restrict the lookup of the
> name immediately following the "::"; the last component of a
> qualified-id is not required to be a class-or-namespace-name, but
> the preceding ones all are. Note that "X::Y" is a qualified-id, even
> if Y is a class or namespace.
>
> --
> William M. Miller, wmm@fastdial.net
> Software Emancipation Technology (www.setech.com)
>
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: fvali@biotrack.com
Date: 1999/07/27 Raw View
In article <7nd4et$ke3$1@nnrp1.deja.com>,
wmm@fastdial.net wrote:
> In article <7n82kt$6d8$1@nnrp1.deja.com>,
> fvali@biotrack.com wrote:
> >
> > Also what about the legality of this silly example:
> >
> > struct A { int x; };
> > A::A::A::A a;
> > a.A::A::A::A:A::x = 10;
>
> That would be well-formed except that 5.1p7 says that "A::A: refers
> to the constructor, not to the injected name of the class, so you
> can't say "A::A::A".
>
If this is what the committee intended then they could have made it
clearer by specifying class-name::class-name anywhere in the
nested-name-specifier would refer to the ctor.
for then it would definitely rule out (since i'm not sure it
umambiguously rules this out as written currently)
struct A { struct B { int x; }; int x; };
A::A::A::B b;
that is assuming the committee actually intended to have these forms be
ill-formed - since I can see why they might not care too much since they
seem relatively harmless.
Anyway the name injection still allows this though, right?
A::B::A::B::A a;
a.A::B::A::B::A::x = 7;
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: aitken17@my-deja.com
Date: 1999/07/27 Raw View
In article <7nd6i1$lqu$1@nnrp1.deja.com>,
wmm@fastdial.net wrote:
> 3.4p1 indirects to 10.2 in requiring that "Name lookup shall find an
> unambiguous declaration for the name."
I don't really think that this is enough. My understanding of your
interpretation of the standard is that if c is of class type C, then
the interpretation of c.A::x involves looking up x in the A sub-objects
of C. It's difficult to justify this based solely on the sentence of
3.4p1 that you quote, or on the general treatment of qualified name
lookup in 3.4.3. Neither does 10.2 mention class member access at all.
> In article <7n94nt$foo$1@nnrp1.deja.com>,
> aitken17@my-deja.com wrote:
> > 2) I'm not convinced I understand what nested-name-specifiers are
> > intended to mean. In particular, I can't find any text (normative
> > or otherwise) that gives them semantics. In particular, they
> > aren't just qualified names followed by :: --- they nest the wrong
> > way round according to the grammar given in 5.1. Am I reading too
> > much into this feature of the concrete syntax? Am I just missing
> > some text, presumably somwhere in clause 3, or perhaps in 5.1?
>
> I'm not sure what you're looking for here. I think the grammar and
> description in 5.1p7 are pretty good. A class-or-namespace-name
> nominates a scope that is then used to restrict the lookup of the
> name immediately following the "::"; the last component of a
> qualified-id is not required to be a class-or-namespace-name, but
> the preceding ones all are. Note that "X::Y" is a qualified-id, even
> if Y is a class or namespace.
>
> --
The difficulties I was having only arise if the /nested-name-
specifier/ has three or more elements. Consider A::B::C::x.
According to the grammar, it nests as if it were (A::(B::(C::)))x.
Consider the /qualified-id/ A::B::C. According to thje grammar it
nests as if it were (A::(B::))C. [Yes, I am aware that parentheses
aren't legal here, but they make a useful notation for indicating
nesting.] Note that in the former, B associates more closely with C,
while in the latter it associates with more closely with A. What this
means is that I can't just use the semantics of the /qualified-id/
A::B::C to understand the semantics of the /nested-name-specifier/
A::B::C::, at least not without some normative text telling me that
it's okay to ignore the difference in their association.
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: wmm@fastdial.net
Date: 1999/07/31 Raw View
In article <7nlcfv$r75$1@nnrp1.deja.com>,
fvali@biotrack.com wrote:
>
> In article <7nd4et$ke3$1@nnrp1.deja.com>,
> wmm@fastdial.net wrote:
> > In article <7n82kt$6d8$1@nnrp1.deja.com>,
> > fvali@biotrack.com wrote:
> > >
> > > Also what about the legality of this silly example:
> > >
> > > struct A { int x; };
> > > A::A::A::A a;
> > > a.A::A::A::A:A::x = 10;
> >
> > That would be well-formed except that 5.1p7 says that "A::A: refers
> > to the constructor, not to the injected name of the class, so you
> > can't say "A::A::A".
> >
> If this is what the committee intended then they could have made it
> clearer by specifying class-name::class-name anywhere in the
> nested-name-specifier would refer to the ctor.
>
> for then it would definitely rule out (since i'm not sure it
> umambiguously rules this out as written currently)
This is an issue that will be on the next Core Language Issues
List as to whether that is, in fact, what the Standard currently
means and/or should say. As it stands currently there is a bit
of a mismatch between 5.1p7, which says that classname::classname
"names the constructor," and 12.1p1, which says that "Constructors
do not have names" and that constructors are only denoted by the
class name occurring in a special form of function declaration,
i.e., by context.
I quoted 5.1p7 in my response because that was the rationale
given for the behavior of the compilers I tried that rejected
your example.
> struct A { struct B { int x; }; int x; };
> A::A::A::B b;
>
> that is assuming the committee actually intended to have these forms
be
> ill-formed - since I can see why they might not care too much since
they
> seem relatively harmless.
For simple cases, yes. However, John Spicer has shown me some
really ugly examples involving template constructors of template
classes that argue in favor of the rule that a class name
appearing after a nested-name-specifier that names the same class
should be considered as denoting the constructor. How persuasive
the Committee will consider those examples is an open question
that I hope will be answered at the October meeting.
> Anyway the name injection still allows this though, right?
> A::B::A::B::A a;
> a.A::B::A::B::A::x = 7;
Assuming that you intended for A::B to be derived from A, yes,
those qualified-ids are well-formed.
--
William M. Miller, wmm@fastdial.net
Software Emancipation Technology (www.setech.com)
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: aitken@nwnexus.com
Date: 1999/07/31 Raw View
In article <7nd73a$m67$1@nnrp1.deja.com>,
wmm@fastdial.net wrote
> In article <7n98c9$hlp$1@nnrp1.deja.com>,
> aitken17@my-deja.com wrote:
>>
>> By this analysis, it seems to me,
>>
>> struct A {int x;};
>> struct B : A {};
>> struct C : A {};
>> struct D : B, C {};
>>
>> D d;
>>
>> d.B::A::x should be ambiguous: the nested-name-specifier (where the
>> lookup starts, according to 10.2p1) is B::A, which is an acceptable
>> way of naming the class A. In the context of D, there is only one
>> class A, but there are multiple A sub-objects, and two A::x
> Your analysis is correct. "B::A" just names a type; the path you
> went through in naming the type is irrelevant in determining which
> "x" you're talking about. The type is used both in the name lookup
> and in the determination of which subobjects of the complete object
> you will consider, but how you named the type in the nested-name-
> specifier is ignored.
I'm bothered by this, since it contradicts an example on pp 394--5 of
Stroustrop's _The C++ Programming Language_. While obviously this
is far from a knock down argument---if Stroustrop and the standard
differ, the standard obviously must take precedence---in a case like
this, where there seems to be some question about what the standard
actually means, it is suggestive that something is amiss.
> You might want to look at the example in 7.3.3p14, which addresses
> the same issue in the context of using-declarations.
I'm not really convinced that this is applicable, it seems to be
illustrating a specific technical point about using declarations,
but I admit that I haven't given it much more than a cursory glance.
>> It seems bizarre in the extreme that d.B::x should be okay (this is
>> how things got started) but d.B::A::x should not.
>
>There's no denying that C++ is sometimes counterintuitive to
>everyone.
I'm not sure I agree with that, although this may be an exception.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: fvali@biotrack.com
Date: 1999/07/22 Raw View
Also what about the legality of this silly example:
struct A { int x; };
A::A::A::A a;
a.A::A::A::A:A::x = 10;
In article <7n5557$4pm$1@nnrp1.deja.com>,
aitken17@my-deja.com wrote:
<snip>
> You are probably right that this is what the committee had in mind,
but
> the wording is unclear to the point of opacity.
>
> So far in this thread, all the examples have been easy, in the sense
> that everyone (who knows C++) knows what the answer should be. But
> what of the following:
>
> struct A {
> int x;
> };
>
> struct E : A {};
> struct F : A {};
>
> F f;
>
> f.E::A::x;
>
> 3.4.5 p.4 allows a case in which E is not found in F, but is found in
> the context of f.E::A::x. I have no idea whether this should be
> legal, but if it is illegal, what about the f.E::A::x in the following
> example?
>
> struct E {
> struct A {int x;};
> struct F : A {};
> };
>
> E::F f;
>
> f.E::A::x;
>
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: fvali@biotrack.com
Date: 1999/07/22 Raw View
In article <7mknh9$fmm$1@nnrp1.deja.com>,
wmm@fastdial.net wrote:
> In article <7mjvr0$7i8$1@nnrp1.deja.com>,
> aitken17@my-deja.com wrote:
> > wmm@fastdial.net wrote:
> > > aitken@halcyon.com (William E. Aitken) wrote:
> > > > consider the following class hierarchy
> > > >
> > > > struct Base {int x;};
> > > > struct A1 : Base {} ;
> > > > struct A2 : Base {} ;
> > > > struct Derived : A1, A2 ;
> > > >
> > > > the idea is to create a class Derived, objects of which have 2
> > > > sub-objects of class Base.
> > > >
> > > > Given the following declaration of der
> > > >
> > > > Derived der;
> > > >
> > > > is der.A1::x supposed to be legal?
> > > >
<snip>
> > class A {int x;};
> > class B : A {};
> > class C : A {} ;
> > class D : B, C {};
> >
> > D d;
> >
> > d.A::x is ambiguous. Right?
> >
<snip>
> Sorry, in my earlier reply I confusingly combined two separate steps
> in the analysis. Instead of "There's only one A1 in Derived," I
> should have said, "There's only one type A1 in Derived, and there's
> only one subobject of type A1 in Derived."
>
ok
> In this example, there's only on type A in D, but there are two
> subobjects of type A in D, so the lookup is ambiguous. The critical
> wording from 10.2p2 is: "First, every declaration for the name in
> the class and in each of its base class sub-objects is considered...
> If... the set has a nonstatic member and includes members from
> distinct sub-objects, there is an ambiguity."
>
ok, perhaps, but see reponse to last paragraph.
> In your first example, the lookup is for the qualified name A1::x;
> that's found in only one subobject, so there's no ambiguity. In
> the second example, the qualified name A::x is found in two
> subobjects, and the name designates a non-static member, so there is
> an ambiguity.
>
According to 3.4.3.1:
Para 1, it is the name after the nested-name-specifier (NNS) of a
qualified id that is looked up in the scope of the class nominated by
the NNS.
So the name that is looked up is always 'x' not A1::x or A::x, and it is
looked up in the scope of A1, or A.
(I) In the first example (der.A1::x) A1 is nominated, and 'x' is found
in one of its base classes 'A1::Base' and according to 10.2 since it is
a non-static member declaration from just one sub-object, name lookup
succeeds. Note as this point name lookup has not been concerned with
the type of our object expresion (der) which is of type 'Derived' at
all.
Now 5.2.5 para 2 specifies that in the postfix expression E1.E2,
where E1 is an object-expression, and E2 is an id-expression (ignoring
templates for now), E2 must name a member of E1. Non-normative text
states that look up for names following the '.' is performed as
specified in 3.4.5, which only really states (as reagards qualified ids)
how the lookup of a class or namespace name immediately following the
'.' is performed.
So A1 is looked up in the context of der.A1::x and found and it is also
found when looked up in the 'Derived' and since they refer to the same
entity, this step proceeds successfully too.
So it is stated that E2 has to name a member of E1 but how exactly is
this verified? Is this a separate step from the one labeled (I) above?
Qualified ids are never looked up - i.e. 'A1::x' isn't looked up
anywhere, since when a qualified-id is used to denote an id-expression,
the unqualified id portion of the qualified-id is looked up in the scope
of the class or namespace nominated by the nested-name-specifier.
If this is a separate step then 'x' is looked up in 'Derived' and found
to be ambiguous and thus ill-formed.
Anyways I don't think this is very clear at all.
If we apply the same steps to d.A::x
'A' is found in both scopes and refers to same entity.
'x' is looked up in 'A' and found to be unambiguous according to 10.2.
'x' is looked up in 'D' and found to be ambiguous.
What am I missing?
-fais
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: aitken17@my-deja.com
Date: 1999/07/23 Raw View
In article <7n5d4e$8dn$1@nnrp1.deja.com>,
wmm@fastdial.net wrote:
> In article <7n5557$4pm$1@nnrp1.deja.com>,
> aitken17@my-deja.com wrote:
> >
> > But what of the following:
> >
> > struct A {
> > int x;
> > };
> >
> > struct E : A {};
> > struct F : A {};
> >
> > F f;
> >
> > f.E::A::x;
> >
> > I have no idea whether this should be legal,
>
> In this case, the nested-name-specifier (where the lookup starts,
> according to 10.2p1) is E::A, which is an acceptable way of naming
> the class A. In the context of F, there's only one A, only one
> A::x, and only one A subobject of F, so the lookup succeeds without
> ambiguity.
>
By this analysis, it seems to me,
struct A {int x;};
struct B : A {};
struct C : A {};
struct D : B, C {};
D d;
d.B::A::x should be ambiguous: the nested-name-specifier (where the
lookup starts, according to 10.2p1) is B::A, which is an acceptable way
of naming the class A. In the context of D, there is only one class A,
but there are multiple A sub-objects, and two A::x
It seems bizarre in the extreme that d.B::x shoudl be okay (this is how
things got stated) but d.B::A::x should not.
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: aitken17@my-deja.com
Date: 1999/07/23 Raw View
In article <7n5d4e$8dn$1@nnrp1.deja.com>,
wmm@fastdial.net wrote:
> In article <7n5557$4pm$1@nnrp1.deja.com>,
> aitken17@my-deja.com wrote:
> > You are probably right that this is what the committee had in mind,
> but
> > the wording is unclear to the point of opacity.
>
> I wouldn't go that far.
I probably was a bit over the top there. My apologies to anyone who
might have been offended.
> The main thing I think is wrong is that
> the description in 10.2 is in terms of an id-expression rather than
> in terms of a class member access expression (as well as the problem
> in issue 39 on the core list). But it could be clearer.
>
> > But
> > what of the following:
> >
> > struct A {
> > int x;
> > };
> >
> > struct E : A {};
> > struct F : A {};
> >
> > F f;
> >
> > f.E::A::x;
> >
>
>
> In this case, the nested-name-specifier (where the lookup starts,
> according to 10.2p1) is E::A, which is an acceptable way of naming
> the class A. In the context of F, there's only one A, only one
> A::x, and only one A subobject of F, so the lookup succeeds without
> ambiguity.
>
Just to be certain I understand. f.E::x would not have been legal
because there is no E sub-object of F. Right?
I think that where I am having trouble is two fold
1) It is not obvious to me why 10.2 applies here [I am not saying that
it's unreasonable that it should, only that I would expect either 3.4.5
or 5.2.5 to say something that pointed in that direction]. For
qualified identifiers follwing the ., 3.4.5 really only talks about the
lookup of the class-or-namespace-name immediately following the . .
5.2.5 requires that in E1.E2, E2 be a member of E1's class or one of
its base classes, but isn't terribly clear how this membership is to be
detrmined, but that's about as close as it gets to pointing at 10.2.
2) I'm not convinced I understand what nested-name-specifiers are
intended to mean. In particular, I can't find any text (normative or
otherwise) that gives them semantics. In particular, they aren't just
qualified names followed by :: --- they nest the wrong way round
according to the grammar given in 5.1. Am I reading too much into
this feature of the concrete syntax? Am I just missing some text,
presumably somwhere in clause 3, or perhaps in 5.1?
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: fvali@biotrack.com
Date: 1999/07/23 Raw View
In article <7mv96k$s3j$1@nnrp1.deja.com>,
wmm@fastdial.net wrote:
> In article <7mo21j$p0h$1@nnrp1.deja.com>,
<snip>
>
> I think the answer is in 10.2p1, which says that if the name being
> looked up is a qualified-id, the lookup begins in the scope of the
> nested-name-specifier. In your original example, the name x is
> looked up "beginning in" A1. That means both that the name must be
> found in the scope of A1 and also that the only subobjects of
> Derived that are considered are A1 and its subobjects. The lookup
> finds the declaration "x" in Base, and there's only one subobject
> of type Base in Derived that is also a subobject of A1, so the
> result is unambiguous.
So 10.2 paragraph 1 is supposed to be saying that for qualified-id's
name lookup begins in the class or base class of the object expression,
denoted by the nested-name specifier - i.e. implying that the class
denoted by the NNS must be a base class of or the same class as the
object epxression.
struct A { int x; };
struct B : A { };
struct C : A { };
struct D : B, C { };
But I'm still not convinced that the standard specifies that the
following is unambiguous.
D d;
d.C::A::x = 10
According to 10.2 p1 lookup begins in 'A' - where does it say that it
begins in C's A - of course this is intuitive, but where in the standard
is it actually documented that it should behave this way and that this
is how nested-name-specifiers work, and how names in the internals of
nested-name-specifiers influence and help to denote the sub-object in
which the unqualified-id of the id-expression is bound to.
>
> In your second example, the lookup begins in A and finds "x" in A.
> This time, though, there are two eligible subobjects of D containing
> the named member, neither having been eliminated by the
> nested-name-specifier, so the result is ambiguous.
>
Where is it stated that the nested-name-specifier helps to eliminate
certain subobjects, and that it always refers to subobjects of the
object-expression?
> (You might find the note and example in 3.4.5p4 illuminating, as
> well.)
But that only talks of the name immediately following the '.' operator.
So for example (refering to the above A,B,C,D) and assuming that 10.2
p1 actualyl does specify that names in qualified-ids are looked up
beginning in the scope of a base-class of the type of the
object-expression then
C c; D d; B b;
c.A::x = 1; // A is found as described in 3.4.5 p4, x is found unambig
d.C::x = 1; // C is found (3.4.5 p4), x is found in A of C.
// C is found, and A is found in C, but x is searched in A of D,
// but which A - and where does the standard say that the nested name
// specifier helps to distinguish and pinpoint which A.
d.C::A::x = 1;
regards,
-fais
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: wmm@fastdial.net
Date: 1999/07/25 Raw View
In article <7n94nt$foo$1@nnrp1.deja.com>,
aitken17@my-deja.com wrote:
> > > But
> > > what of the following:
> > >
> > > struct A {
> > > int x;
> > > };
> > >
> > > struct E : A {};
> > > struct F : A {};
> > >
> > > F f;
> > >
> > > f.E::A::x;
> > >
> >
> >
> > In this case, the nested-name-specifier (where the lookup starts,
> > according to 10.2p1) is E::A, which is an acceptable way of naming
> > the class A. In the context of F, there's only one A, only one
> > A::x, and only one A subobject of F, so the lookup succeeds without
> > ambiguity.
> >
>
> Just to be certain I understand. f.E::x would not have been legal
> because there is no E sub-object of F. Right?
Right.
> I think that where I am having trouble is two fold
>
> 1) It is not obvious to me why 10.2 applies here [I am not saying that
> it's unreasonable that it should, only that I would expect either
3.4.5
> or 5.2.5 to say something that pointed in that direction]. For
> qualified identifiers follwing the ., 3.4.5 really only talks about
the
> lookup of the class-or-namespace-name immediately following the . .
> 5.2.5 requires that in E1.E2, E2 be a member of E1's class or one of
> its base classes, but isn't terribly clear how this membership is to
be
> detrmined, but that's about as close as it gets to pointing at 10.2.
3.4p1 indirects to 10.2 in requiring that "Name lookup shall find an
unambiguous declaration for the name." 3.4.5p4 only talks about
the first component of the nested-name-specifier because it's really
just describing how to interpret a nested-name-specifier in a class
member access expression; after you've figured out the scope the
nested-name-specifier nominates, it's just an ordinary qualified
name lookup, described in 3.4.3.1p1 (which also indirects to 10.2).
5.2.5 doesn't say anything about lookup, it's just stating the
semantics once the names in the expression have been associated with
declarations by the lookup process.
> 2) I'm not convinced I understand what nested-name-specifiers are
> intended to mean. In particular, I can't find any text (normative or
> otherwise) that gives them semantics. In particular, they aren't
just
> qualified names followed by :: --- they nest the wrong way round
> according to the grammar given in 5.1. Am I reading too much into
> this feature of the concrete syntax? Am I just missing some text,
> presumably somwhere in clause 3, or perhaps in 5.1?
I'm not sure what you're looking for here. I think the grammar and
description in 5.1p7 are pretty good. A class-or-namespace-name
nominates a scope that is then used to restrict the lookup of the
name immediately following the "::"; the last component of a
qualified-id is not required to be a class-or-namespace-name, but
the preceding ones all are. Note that "X::Y" is a qualified-id, even
if Y is a class or namespace.
--
William M. Miller, wmm@fastdial.net
Software Emancipation Technology (www.setech.com)
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: wmm@fastdial.net
Date: 1999/07/25 Raw View
In article <7n82kt$6d8$1@nnrp1.deja.com>,
fvali@biotrack.com wrote:
>
> Also what about the legality of this silly example:
>
> struct A { int x; };
> A::A::A::A a;
> a.A::A::A::A:A::x = 10;
That would be well-formed except that 5.1p7 says that "A::A: refers
to the constructor, not to the injected name of the class, so you
can't say "A::A::A".
--
William M. Miller, wmm@fastdial.net
Software Emancipation Technology (www.setech.com)
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: wmm@fastdial.net
Date: 1999/07/25 Raw View
In article <7n827h$68g$1@nnrp1.deja.com>,
fvali@biotrack.com wrote:
> In article <7mv96k$s3j$1@nnrp1.deja.com>,
> wmm@fastdial.net wrote:
> > In article <7mo21j$p0h$1@nnrp1.deja.com>,
> <snip>
> >
> > I think the answer is in 10.2p1, which says that if the name being
> > looked up is a qualified-id, the lookup begins in the scope of the
> > nested-name-specifier. In your original example, the name x is
> > looked up "beginning in" A1. That means both that the name must be
> > found in the scope of A1 and also that the only subobjects of
> > Derived that are considered are A1 and its subobjects. The lookup
> > finds the declaration "x" in Base, and there's only one subobject
> > of type Base in Derived that is also a subobject of A1, so the
> > result is unambiguous.
>
> So 10.2 paragraph 1 is supposed to be saying that for qualified-id's
> name lookup begins in the class or base class of the object
expression,
> denoted by the nested-name specifier - i.e. implying that the class
> denoted by the NNS must be a base class of or the same class as the
> object epxression.
That's right.
> struct A { int x; };
> struct B : A { };
> struct C : A { };
> struct D : B, C { };
>
> But I'm still not convinced that the standard specifies that the
> following is unambiguous.
>
> D d;
> d.C::A::x = 10
With good reason -- it doesn't say that. That is an ambiguous
reference. "C::A" just names a type. It's the same type that is
named by "B::A" or "A". So the lookup begins in every subobject
of D that is of the named type. It turns out that there are two
such subobjects, and the result of the lookup is a nonstatic data
member, so the lookup is ambiguous.
> According to 10.2 p1 lookup begins in 'A' - where does it say that it
> begins in C's A - of course this is intuitive, but where in the
standard
> is it actually documented that it should behave this way and that this
> is how nested-name-specifiers work, and how names in the internals of
> nested-name-specifiers influence and help to denote the sub-object in
> which the unqualified-id of the id-expression is bound to.
It doesn't say that.
> >
> > In your second example, the lookup begins in A and finds "x" in A.
> > This time, though, there are two eligible subobjects of D containing
> > the named member, neither having been eliminated by the
> > nested-name-specifier, so the result is ambiguous.
> >
> Where is it stated that the nested-name-specifier helps to eliminate
> certain subobjects, and that it always refers to subobjects of the
> object-expression?
It's not as clear as I'd like (which is why I said that some
clarification may be in order when we look at the pending issue in
this section).
10.2p1 is written with respect to an id-expression in a member
function (hence the reference to "this"). Because such an expression
is translated into member access expression (9.3.1p2), it seemed
reasonable to extrapolate from (*this).<whatever> to other forms of
object expression.
The only way I can understand the relationship between 10.2p1 and
10.2p2 is that p1 imposes restrictions on p2. If the "lookup begins
in the scope of the nested-name-specifier", then I don't see any way
that the lookup could find a name declared in a class other than that
of the nested-name-specifier or one of its subobjects, even though
10.2p2 says that names in the complete object's class are "considered."
However, 10.2p2 _does_ talk about doing the lookup in "each of its
base class sub-objects." Reading 10.2p1 as a limitation on 10.2p2,
I take that to mean that sub-objects that are neither the class of
the nested-name-specifier nor one of its sub-objects are not
considered.
> > (You might find the note and example in 3.4.5p4 illuminating, as
> > well.)
>
> But that only talks of the name immediately following the '.'
operator.
Right. In that case there are two "B" subobjects of E, but the
class in which the name "a" is found is represented by only one
subobject in E, so the result is unambiguous. (Note that the
description in 10.2p2 is _not_ recursive -- the sub-objects are
sub-objects of the object, direct and indirect.)
> So for example (refering to the above A,B,C,D) and assuming that 10.2
> p1 actualyl does specify that names in qualified-ids are looked up
> beginning in the scope of a base-class of the type of the
> object-expression then
> C c; D d; B b;
> c.A::x = 1; // A is found as described in 3.4.5 p4, x is found unambig
> d.C::x = 1; // C is found (3.4.5 p4), x is found in A of C.
That's right. We find A::x doing the lookup in C, and there's only
one A subobject in D that is also a sub-object of C.
> // C is found, and A is found in C, but x is searched in A of D,
> // but which A - and where does the standard say that the nested name
> // specifier helps to distinguish and pinpoint which A.
> d.C::A::x = 1;
C::A is where the lookup begins (10.2p1), we find A::x, but there
are two sub-objects of that type in D and the declaration found by
the lookup in C::A is a nonstatic data member, so it's ambiguous.
--
William M. Miller, wmm@fastdial.net
Software Emancipation Technology (www.setech.com)
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: wmm@fastdial.net
Date: 1999/07/20 Raw View
In article <7mo21j$p0h$1@nnrp1.deja.com>,
aitken17@my-deja.com wrote:
> In article <7mknh9$fmm$1@nnrp1.deja.com>,
> wmm@fastdial.net wrote:
> > In article <7mjvr0$7i8$1@nnrp1.deja.com>,
> > aitken17@my-deja.com wrote:
> > > wmm@fastdial.net wrote:
> > > > aitken@halcyon.com (William E. Aitken) wrote:
> > > > > consider the following class hierarchy
> > > > >
> > > > > struct Base {int x;};
> > > > > struct A1 : Base {} ;
> > > > > struct A2 : Base {} ;
> > > > > struct Derived : A1, A2 ;
> > > > >
> > > > > the idea is to create a class Derived, objects of which have 2
> > > > > sub-objects of class Base.
> > > > >
> > > > > Given the following declaration of der
> > > > >
> > > > > Derived der;
> > > > >
> > > > > is der.A1::x supposed to be legal?
> > > > >
> > > > > I would claim that there is strong evidence that the C++
community
> > > > > believes it should be. See, for example, Stroustrop, _the
C++
> > > > > Programming Language_, 3rd edition, pp. 394--395.
Nevertheless,
> > > > > this is not really terribly clear
> > > > > from the standard. In particular, the standard seems to
believe that
> > > > > . and :: can be treated entirely compositionally in this
instance: if
> > > > > it doesn't then there needs to be _some_ language to the
contrary.
> > > > > A1::x refers to the x field of Base. But there are two such
subfields
> > > > > of der, so the expression seems to be ambiguous.
> > > > >
> > > > > There are three obvious ways around this discrepancy.
> > > > > (1) my interpretation of the sentiment of the community is
wrong:
> > > > > der.A1::x should be ambiguous.
> > > > > (2) :: after . isn't compositional.... but then where is the
> > > > > language that makes this so?
> > > > > (3) A1::x refers to the x field that A1 inherits from Base.
> > > > > That is, the involvement of A1 is recorded. I don't really
believe
> > > > > that the standard admits this interpretation, but I'd be happy
to be
> > > > > convinced otherwise.
> > > >
> > > > Could you point out what in the Standard makes you think this
> > > > should be ambiguous? 10.2 and 3.4.5 seem pretty clear that for
> > > > der.A1::x, the lookup for A1 is in the context of Derived, and
> > > > the lookup for x is in the context of A1. There's only one A1
> > > > in Derived and only one x in A1, so there's no ambiguity.
> > >
> > > I don't buy it. Consider the following
> > >
> > > class A {int x;};
> > > class B : A {};
> > > class C : A {} ;
> > > class D : B, C {};
> > >
> > > D d;
> > >
> > > d.A::x is ambiguous. Right?
> > >
> > > But looking up A in D doesn't yield an ambiguity: A is always
found in
> > > the same class, and is static. Looking up x in A is unambiguous.
> >
> > Sorry, in my earlier reply I confusingly combined two separate steps
> > in the analysis. Instead of "There's only one A1 in Derived," I
> > should have said, "There's only one type A1 in Derived, and there's
> > only one subobject of type A1 in Derived."
> >
> > In this example, there's only on type A in D, but there are two
> > subobjects of type A in D, so the lookup is ambiguous. The critical
> > wording from 10.2p2 is: "First, every declaration for the name in
> > the class and in each of its base class sub-objects is considered...
> > If... the set has a nonstatic member and includes members from
> > distinct sub-objects, there is an ambiguity."
> >
> > In your first example, the lookup is for the qualified name A1::x;
> > that's found in only one subobject, so there's no ambiguity. In
> > the second example, the qualified name A::x is found in two
> > subobjects, and the name designates a non-static member, so there is
> > an ambiguity.
>
> Okay. It seems to me that you are proposing that the semantics are
> something like this. Please correct me if I am wrong.
>
> You encounter something like d.A::x. First, consider every
> declaration in D and in any of its base class sub-objects that
declares
> A::x. Now do the usual name hiding stuff to remove some declarations
> from consideration. If x is non-static, you must end up with exactly
1
> declaration; otherwise, it suffices for all declarations left to come
> from sub-objects of the same type.
>
> So far, so good. This is just 10.2 paragraph 2. The real question
I
> have had all along is what does it mean for a declaration to be a
> declaration of A::x? It seems that the answer you are advocating is
> that the declaration must be a declaration of x that occurs in a sub-
> object of an a sub-object of D. I'm having trouble finding normative
> language in the standard to support this though.
I think the answer is in 10.2p1, which says that if the name being
looked up is a qualified-id, the lookup begins in the scope of the
nested-name-specifier. In your original example, the name x is
looked up "beginning in" A1. That means both that the name must be
found in the scope of A1 and also that the only subobjects of
Derived that are considered are A1 and its subobjects. The lookup
finds the declaration "x" in Base, and there's only one subobject
of type Base in Derived that is also a subobject of A1, so the
result is unambiguous.
In your second example, the lookup begins in A and finds "x" in A.
This time, though, there are two eligible subobjects of D containing
the named member, neither having been eliminated by the
nested-name-specifier, so the result is ambiguous.
(You might find the note and example in 3.4.5p4 illuminating, as
well.)
I don't think this is necessarily as clear as it might be in 10.2.
There is already an issue in 10.2 (# 39 on the Core Language Issues
List), so perhaps this could be clarified in the rewording that will
be required to resolve that issue.
--
William M. Miller, wmm@fastdial.net
Software Emancipation Technology (www.setech.com)
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: aitken17@my-deja.com
Date: 1999/07/21 Raw View
In article <7mv96k$s3j$1@nnrp1.deja.com>,
wmm@fastdial.net wrote:
>
> I don't think this is necessarily as clear as it might be in 10.2.
> There is already an issue in 10.2 (# 39 on the Core Language Issues
> List), so perhaps this could be clarified in the rewording that will
> be required to resolve that issue.
>
You are probably right that this is what the committee had in mind, but
the wording is unclear to the point of opacity.
So far in this thread, all the examples have been easy, in the sense
that everyone (who knows C++) knows what the answer should be. But
what of the following:
struct A {
int x;
};
struct E : A {};
struct F : A {};
F f;
f.E::A::x;
3.4.5 p.4 allows a case in which E is not found in F, but is found in
the context of f.E::A::x. I have no idea whether this should be
legal, but if it is illegal, what about the f.E::A::x in the following
example?
struct E {
struct A {int x;};
struct F : A {};
};
E::F f;
f.E::A::x;
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: wmm@fastdial.net
Date: 1999/07/22 Raw View
In article <7n5557$4pm$1@nnrp1.deja.com>,
aitken17@my-deja.com wrote:
> In article <7mv96k$s3j$1@nnrp1.deja.com>,
> wmm@fastdial.net wrote:
>
> >
> > I don't think this is necessarily as clear as it might be in 10.2.
> > There is already an issue in 10.2 (# 39 on the Core Language Issues
> > List), so perhaps this could be clarified in the rewording that will
> > be required to resolve that issue.
> >
>
> You are probably right that this is what the committee had in mind,
but
> the wording is unclear to the point of opacity.
I wouldn't go that far. The main thing I think is wrong is that
the description in 10.2 is in terms of an id-expression rather than
in terms of a class member access expression (as well as the problem
in issue 39 on the core list). But it could be clearer.
> So far in this thread, all the examples have been easy, in the sense
> that everyone (who knows C++) knows what the answer should be. But
> what of the following:
>
> struct A {
> int x;
> };
>
> struct E : A {};
> struct F : A {};
>
> F f;
>
> f.E::A::x;
>
> 3.4.5 p.4 allows a case in which E is not found in F, but is found in
> the context of f.E::A::x. I have no idea whether this should be
> legal,
It is. The main point of 3.4.5p4 is that the in-class lookup and
the expression-scope lookup must not disagree; if one or the other
comes up empty, the one that succeeds is used without complaint.
In this case, the nested-name-specifier (where the lookup starts,
according to 10.2p1) is E::A, which is an acceptable way of naming
the class A. In the context of F, there's only one A, only one
A::x, and only one A subobject of F, so the lookup succeeds without
ambiguity.
> but if it is illegal, what about the f.E::A::x in the following
> example?
>
> struct E {
> struct A {int x;};
> struct F : A {};
> };
>
> E::F f;
>
> f.E::A::x;
This one's fine, too. In both cases, the fact that the first
component of the nested-name-specifier is not found in the class of
the object expression is no problem; the entire nested-name-specifier
is what counts, and in both cases it names a class that is a unique
subobject of the class of the object expression.
--
William M. Miller, wmm@fastdial.net
Software Emancipation Technology (www.setech.com)
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: aitken17@my-deja.com
Date: 1999/07/15 Raw View
wmm@fastdial.net wrote:
> aitken@halcyon.com (William E. Aitken) wrote:
> > consider the following class hierarchy
> >
> > struct Base {int x;};
> > struct A1 : Base {} ;
> > struct A2 : Base {} ;
> > struct Derived : A1, A2 ;
> >
> > the idea is to create a class Derived, objects of which have 2
> > sub-objects of class Base.
> >
> > Given the following declaration of der
> >
> > Derived der;
> >
> > is der.A1::x supposed to be legal?
> >
> > I would claim that there is strong evidence that the C++ community
> > believes it should be. See, for example, Stroustrop, _the C++
> > Programming Language_, 3rd edition, pp. 394--395. Nevertheless,
> > this is not really terribly clear
> > from the standard. In particular, the standard seems to believe that
> > . and :: can be treated entirely compositionally in this instance: if it
> > doesn't then there needs to be _some_ language to the contrary. A1::x
> > refers to the x field of Base. But there are two such subfields of der,
> > so the expression seems to be ambiguous.
> >
> > There are three obvious ways around this discrepancy.
> > (1) my interpretation of the sentiment of the community is wrong:
> > der.A1::x should be ambiguous.
> > (2) :: after . isn't compositional.... but then where is the
> > language that makes this so?
> > (3) A1::x refers to the x field that A1 inherits from Base.
> > That is, the involvement of A1 is recorded. I don't really believe
> > that the standard admits this interpretation, but I'd be happy to be
> > convinced otherwise.
>
> Could you point out what in the Standard makes you think this
> should be ambiguous? 10.2 and 3.4.5 seem pretty clear that for
> der.A1::x, the lookup for A1 is in the context of Derived, and
> the lookup for x is in the context of A1. There's only one A1
> in Derived and only one x in A1, so there's no ambiguity.
I don't buy it. Consider the following
class A {int x;};
class B : A {};
class C : A {} ;
class D : B, C {};
D d;
d.A::x is ambiguous. Right?
But looking up A in D doesn't yield an ambiguity: A is always found in
the same class, and is static. Looking up x in A is unambiguous.
Bill
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Salters <msalters@lucent.com>
Date: 1999/07/16 Raw View
aitken17@my-deja.com wrote:
[SNIP]
> Consider the following
>
> class A {int x;};
> class B : A {};
> class C : A {} ;
> class D : B, C {};
>
> D d;
>
> d.A::x is ambiguous. Right?
Yes: A is not a virtual base, so D contains two A subobjects.
> But looking up A in D doesn't yield an ambiguity: A is always found in
> the same class, and is static. Looking up x in A is unambiguous.
I'm not sure what you mean by "looking up", nor what you mean by "static".
"static" is a C++ keyword, meaning that a member is not tied to a specific
instance of a class, but is shared between all instances. I.e. if D has a
static member E, and you have two D objects, you have one E object. A
clearly isn't static: If you have two D's, you have 4 A's.
If you don't believe it, add output to the ctor & dtor of A.
i.e.
static int howmanyA=0;
A::A {
cout << "ctor A called. There are now " << ++howmanyA << "A objects" <<endl;
}
A::~A {
cout << "dtor A called. There are now " << --howmanyA << "A objects" <<endl;
}
Casting a D* to an A* will give unpredictable results.
Michiel Salters
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: wmm@fastdial.net
Date: 1999/07/16 Raw View
In article <7mjvr0$7i8$1@nnrp1.deja.com>,
aitken17@my-deja.com wrote:
> wmm@fastdial.net wrote:
> > aitken@halcyon.com (William E. Aitken) wrote:
> > > consider the following class hierarchy
> > >
> > > struct Base {int x;};
> > > struct A1 : Base {} ;
> > > struct A2 : Base {} ;
> > > struct Derived : A1, A2 ;
> > >
> > > the idea is to create a class Derived, objects of which have 2
> > > sub-objects of class Base.
> > >
> > > Given the following declaration of der
> > >
> > > Derived der;
> > >
> > > is der.A1::x supposed to be legal?
> > >
> > > I would claim that there is strong evidence that the C++ community
> > > believes it should be. See, for example, Stroustrop, _the C++
> > > Programming Language_, 3rd edition, pp. 394--395. Nevertheless,
> > > this is not really terribly clear
> > > from the standard. In particular, the standard seems to believe
that
> > > . and :: can be treated entirely compositionally in this instance:
if it
> > > doesn't then there needs to be _some_ language to the contrary.
A1::x
> > > refers to the x field of Base. But there are two such subfields
of der,
> > > so the expression seems to be ambiguous.
> > >
> > > There are three obvious ways around this discrepancy.
> > > (1) my interpretation of the sentiment of the community is wrong:
> > > der.A1::x should be ambiguous.
> > > (2) :: after . isn't compositional.... but then where is the
> > > language that makes this so?
> > > (3) A1::x refers to the x field that A1 inherits from Base.
> > > That is, the involvement of A1 is recorded. I don't really
believe
> > > that the standard admits this interpretation, but I'd be happy to
be
> > > convinced otherwise.
> >
> > Could you point out what in the Standard makes you think this
> > should be ambiguous? 10.2 and 3.4.5 seem pretty clear that for
> > der.A1::x, the lookup for A1 is in the context of Derived, and
> > the lookup for x is in the context of A1. There's only one A1
> > in Derived and only one x in A1, so there's no ambiguity.
>
> I don't buy it. Consider the following
>
> class A {int x;};
> class B : A {};
> class C : A {} ;
> class D : B, C {};
>
> D d;
>
> d.A::x is ambiguous. Right?
>
> But looking up A in D doesn't yield an ambiguity: A is always found in
> the same class, and is static. Looking up x in A is unambiguous.
Sorry, in my earlier reply I confusingly combined two separate steps
in the analysis. Instead of "There's only one A1 in Derived," I
should have said, "There's only one type A1 in Derived, and there's
only one subobject of type A1 in Derived."
In this example, there's only on type A in D, but there are two
subobjects of type A in D, so the lookup is ambiguous. The critical
wording from 10.2p2 is: "First, every declaration for the name in
the class and in each of its base class sub-objects is considered...
If... the set has a nonstatic member and includes members from
distinct sub-objects, there is an ambiguity."
In your first example, the lookup is for the qualified name A1::x;
that's found in only one subobject, so there's no ambiguity. In
the second example, the qualified name A::x is found in two
subobjects, and the name designates a non-static member, so there is
an ambiguity.
--
William M. Miller, wmm@fastdial.net
Software Emancipation Technology (www.setech.com)
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: aitken17@my-deja.com
Date: 1999/07/19 Raw View
In article <7mknh9$fmm$1@nnrp1.deja.com>,
wmm@fastdial.net wrote:
> In article <7mjvr0$7i8$1@nnrp1.deja.com>,
> aitken17@my-deja.com wrote:
> > wmm@fastdial.net wrote:
> > > aitken@halcyon.com (William E. Aitken) wrote:
> > > > consider the following class hierarchy
> > > >
> > > > struct Base {int x;};
> > > > struct A1 : Base {} ;
> > > > struct A2 : Base {} ;
> > > > struct Derived : A1, A2 ;
> > > >
> > > > the idea is to create a class Derived, objects of which have 2
> > > > sub-objects of class Base.
> > > >
> > > > Given the following declaration of der
> > > >
> > > > Derived der;
> > > >
> > > > is der.A1::x supposed to be legal?
> > > >
> > > > I would claim that there is strong evidence that the C++ community
> > > > believes it should be. See, for example, Stroustrop, _the C++
> > > > Programming Language_, 3rd edition, pp. 394--395. Nevertheless,
> > > > this is not really terribly clear
> > > > from the standard. In particular, the standard seems to believe that
> > > > . and :: can be treated entirely compositionally in this instance: if
> > > > it doesn't then there needs to be _some_ language to the contrary.
> > > > A1::x refers to the x field of Base. But there are two such subfields
> > > > of der, so the expression seems to be ambiguous.
> > > >
> > > > There are three obvious ways around this discrepancy.
> > > > (1) my interpretation of the sentiment of the community is wrong:
> > > > der.A1::x should be ambiguous.
> > > > (2) :: after . isn't compositional.... but then where is the
> > > > language that makes this so?
> > > > (3) A1::x refers to the x field that A1 inherits from Base.
> > > > That is, the involvement of A1 is recorded. I don't really believe
> > > > that the standard admits this interpretation, but I'd be happy to be
> > > > convinced otherwise.
> > >
> > > Could you point out what in the Standard makes you think this
> > > should be ambiguous? 10.2 and 3.4.5 seem pretty clear that for
> > > der.A1::x, the lookup for A1 is in the context of Derived, and
> > > the lookup for x is in the context of A1. There's only one A1
> > > in Derived and only one x in A1, so there's no ambiguity.
> >
> > I don't buy it. Consider the following
> >
> > class A {int x;};
> > class B : A {};
> > class C : A {} ;
> > class D : B, C {};
> >
> > D d;
> >
> > d.A::x is ambiguous. Right?
> >
> > But looking up A in D doesn't yield an ambiguity: A is always found in
> > the same class, and is static. Looking up x in A is unambiguous.
>
> Sorry, in my earlier reply I confusingly combined two separate steps
> in the analysis. Instead of "There's only one A1 in Derived," I
> should have said, "There's only one type A1 in Derived, and there's
> only one subobject of type A1 in Derived."
>
> In this example, there's only on type A in D, but there are two
> subobjects of type A in D, so the lookup is ambiguous. The critical
> wording from 10.2p2 is: "First, every declaration for the name in
> the class and in each of its base class sub-objects is considered...
> If... the set has a nonstatic member and includes members from
> distinct sub-objects, there is an ambiguity."
>
> In your first example, the lookup is for the qualified name A1::x;
> that's found in only one subobject, so there's no ambiguity. In
> the second example, the qualified name A::x is found in two
> subobjects, and the name designates a non-static member, so there is
> an ambiguity.
Okay. It seems to me that you are proposing that the semantics are
something like this. Please correct me if I am wrong.
You encounter something like d.A::x. First, consider every
declaration in D and in any of its base class sub-objects that declares
A::x. Now do the usual name hiding stuff to remove some declarations
from consideration. If x is non-static, you must end up with exactly 1
declaration; otherwise, it suffices for all declarations left to come
from sub-objects of the same type.
So far, so good. This is just 10.2 paragraph 2. The real question I
have had all along is what does it mean for a declaration to be a
declaration of A::x? It seems that the answer you are advocating is
that the declaration must be a declaration of x that occurs in a sub-
object of an a sub-object of D. I'm having trouble finding normative
language in the standard to support this though.
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: aitken17@my-deja.com
Date: 1999/07/19 Raw View
In article <378D906F.6FA593D1@lucent.com>,
Salters <msalters@lucent.com> wrote:
> aitken17@my-deja.com wrote:
>
> [SNIP]
>
> > Consider the following
> >
> > class A {int x;};
> > class B : A {};
> > class C : A {} ;
> > class D : B, C {};
> >
> > D d;
> >
> > d.A::x is ambiguous. Right?
>
> Yes: A is not a virtual base, so D contains two A subobjects.
>
> > But looking up A in D doesn't yield an ambiguity: A is always found
in
> > the same class, and is static. Looking up x in A is unambiguous.
>
> I'm not sure what you mean by "looking up", nor what you mean by
"static".
Lookup is defined in the standard. As for my use of static, I was
trying to capture 10.2 paragraph 5 succinctly, my apologies if I caused
confusion.
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: wmm@fastdial.net
Date: 1999/06/29 Raw View
In article <7l0l52$hj7$1@halcyon.com>,
aitken@halcyon.com (William E. Aitken) wrote:
> consider the following class hierarchy
>
> struct Base {int x;};
> struct A1 : Base {} ;
> struct A2 : Base {} ;
> struct Derived : A1, A2 ;
>
> the idea is to create a class Derived, objects of which have 2
sub-objects of
> class Base.
>
> Given the following declaration of der
>
> Derived der;
>
> is der.A1::x supposed to be legal?
>
> I would claim that there is strong evidence that the C++ community
believes
> it should be. See, for example, Stroustrop, _the C++ Programming
Language_,
> 3rd edition, pp. 394--395. Nevertheless, this is not really terribly
clear
> from the standard. In particular, the standard seems to believe that
. and ::
> can be treated entirely compositionally in this instance: if it
doesn't
> then there needs to be _some_ language to the contrary. A1::x refers
> to the x field of Base. But there are two such subfields of der, so
> the expression seems to be ambiguous.
>
> There are three obvious ways around this discrepancy. (1) my
interpretation
> of the sentiment of the community is wrong: der.A1::x should be
ambiguous.
> (2) :: after . isn't compositional.... but then where is the language
that
> makes this so? (3) A1::x refers to the x field that A1 inherits from
Base.
> That is, the involvement of A1 is recorded. I don't really believe
that
> the standard admits this interpretation, but I'd be happy to be
convinced
> otherwise.
Could you point out what in the Standard makes you think this
should be ambiguous? 10.2 and 3.4.5 seem pretty clear that for
der.A1::x, the lookup for A1 is in the context of Derived, and
the lookup for x is in the context of A1. There's only one A1
in Derived and only one x in A1, so there's no ambiguity.
--
William M. Miller, wmm@fastdial.net
Software Emancipation Technology (www.setech.com)
Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: aitken@halcyon.com (William E. Aitken)
Date: 1999/06/26 Raw View
consider the following class hierarchy
struct Base {int x;};
struct A1 : Base {} ;
struct A2 : Base {} ;
struct Derived : A1, A2 ;
the idea is to create a class Derived, objects of which have 2 sub-objects of
class Base.
Given the following declaration of der
Derived der;
is der.A1::x supposed to be legal?
I would claim that there is strong evidence that the C++ community believes
it should be. See, for example, Stroustrop, _the C++ Programming Language_,
3rd edition, pp. 394--395. Nevertheless, this is not really terribly clear
from the standard. In particular, the standard seems to believe that . and ::
can be treated entirely compositionally in this instance: if it doesn't
then there needs to be _some_ language to the contrary. A1::x refers
to the x field of Base. But there are two such subfields of der, so
the expression seems to be ambiguous.
There are three obvious ways around this discrepancy. (1) my interpretation
of the sentiment of the community is wrong: der.A1::x should be ambiguous.
(2) :: after . isn't compositional.... but then where is the language that
makes this so? (3) A1::x refers to the x field that A1 inherits from Base.
That is, the involvement of A1 is recorded. I don't really believe that
the standard admits this interpretation, but I'd be happy to be convinced
otherwise.
So what do people think?
--
William E. Aitken | Formal verification is the
email: aitken@halcyon.com | future of computer science ---
Snail: 6124 86th Ave SE Mercer Island WA | Always has been, always will be.
===============================================================================
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]