Topic: How is "~T" looked up as a name in a class scope?
Author: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Thu, 14 Jan 2010 12:37:45 CST Raw View
And how are injected class names looked up? Is the following valid?
namespace N { struct A { }; }
int main() { typedef N::A At; N::A a; a.~At(); }
The corresponding rule at 3.4.5/3 of n3000 says:
"If the unqualified-id is ~type-name, the type-name is looked up in the
context of the entire postfix-expression. If the type T of the object
expression is of a class type C, the type-name is also looked up in the
scope of class C. At least one of the lookups shall find a name that refers
to (possibly cv-qualified) T."
Looking up "At" in the scope of the class according to 10.2 will look for
declarations of names "At". To me there do not seem to be such declarations.
However, there is this wording at 10.2/4:
"the declaration set, a set of members named f; [...]. In the declaration
set, using-declarations are replaced by the members they designate, and type
declarations (including injected-class-names) are replaced by the types they
designate."
Will this allow "At" to be found? And if yes, what will the declaration set
contain? The declaration set is said to contain a set of declarations, but
how will a *type* fit into such a set? And won't we will first have to find
a declaration for "At" to be able to replace it by "N::A" and see that "At"
and "N::A" denote the same type?. What is the purpose of that rule?
Also, how will access checking proceeed?
struct A { };
struct B : private A { };
int main() { B::A a; }
If lookup into B for A will replace "B::A" by the declaration ::A (if that
is meant by "the type they designate") which is the result of the lookup,
then won't this make uses of B::A slip through as valid?
What do i miss here? Thanks for any answers!
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use
mailto:std-c++@netlab.cs.rpi.edu<std-c%2B%2B@netlab.cs.rpi.edu>
]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Kaz Kylheku <kkylheku@gmail.com>
Date: Thu, 14 Jan 2010 22:29:45 CST Raw View
On 2010-01-14, Johannes Schaub (litb) <schaub-johannes@web.de> wrote:
> And how are injected class names looked up? Is the following valid?
>
> namespace N { struct A { }; }
> int main() { typedef N::A At; N::A a; a.~At(); }
>
> The corresponding rule at 3.4.5/3 of n3000 says:
>
> "If the unqualified-id is ~type-name, the type-name is looked up in the
> context of the entire postfix-expression. If the type T of the object
> expression is of a class type C, the type-name is also looked up in the
> scope of class C. At least one of the lookups shall find a name that refers
> to (possibly cv-qualified) T."
>
> Looking up "At" in the scope of the class according to 10.2 will look for
> declarations of names "At". To me there do not seem to be such declarations.
However, there is a declarationf for At in ``the context of the entire
postfix-expression''.
If the object expression (the stuff to the left of the dot) is a class,
then the type name is /ALSO/ looked up in the scope of its class.
^^^^^^^
I.e. this class scope lookup is in addition to lookup in the context of the
expression.
(This is funny wording; in what correct circumstances is the object in a member
selection postfix expression /not/ of a class type?)
>
> However, there is this wording at 10.2/4:
>
>
> "the declaration set, a set of members named f; [...]. In the declaration
> set, using-declarations are replaced by the members they designate, and type
> declarations (including injected-class-names) are replaced by the types they
> designate."
>
> Will this allow "At" to be found? And if yes, what will the declaration set
> contain? The declaration set is said to contain a set of declarations, but
> how will a *type* fit into such a set? And won't we will first have to find
> a declaration for "At" to be able to replace it by "N::A" and see that "At"
> and "N::A" denote the same type?. What is the purpose of that rule?
Declarations aren't textual macros. At actually is the same type from which
the object a was instantiated; it does not merely typographically denote the
syntax "N::A".
> Also, how will access checking proceeed?
>
> struct A { };
> struct B : private A { };
>
> int main() { B::A a; }
This is erroneous. The name A is a private member of class scope B,
and main is not a member funtion of B.
> If lookup into B for A will replace "B::A" by the declaration ::A (if that
> is meant by "the type they designate") which is the result of the lookup,
> then won't this make uses of B::A slip through as valid?
No, because the C++ type system is not a macro processor (at least
not an unhygienic one).
The expression B::A performs scope resolution, and that is subject
to access restrictions based on the scope in which it occurs.
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: CornedBee <wasti.redl@gmx.net>
Date: Fri, 15 Jan 2010 11:23:51 CST Raw View
On Jan 15, 5:29 am, Kaz Kylheku <kkylh...@gmail.com> wrote:
>
> However, there is a declarationf for At in ``the context of the entire
> postfix-expression''.
>
> If the object expression (the stuff to the left of the dot) is a class,
> then the type name is /ALSO/ looked up in the scope of its class.
> ^^^^^^^
>
> I.e. this class scope lookup is in addition to lookup in the context of the
> expression.
>
> (This is funny wording; in what correct circumstances is the object in a member
> selection postfix expression /not/ of a class type?)
>
Pseudo-destructor calls, i.e when you do
[code]template <typename T>
void destroy(T *p) {
p->~T();
}
int *pi = whatever();
destroy(pi);[/code]
Sebastian
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Johannes Schaub (litb)" <schaub-johannes@web.de>
Date: Fri, 15 Jan 2010 11:24:10 CST Raw View
Kaz Kylheku wrote:
> On 2010-01-14, Johannes Schaub (litb) <schaub-johannes@web.de> wrote:
>> And how are injected class names looked up? Is the following valid?
>>
>> namespace N { struct A { }; }
>> int main() { typedef N::A At; N::A a; a.~At(); }
>>
>> The corresponding rule at 3.4.5/3 of n3000 says:
>>
>> "If the unqualified-id is ~type-name, the type-name is looked up in the
>> context of the entire postfix-expression. If the type T of the object
>> expression is of a class type C, the type-name is also looked up in the
>> scope of class C. At least one of the lookups shall find a name that
>> refers to (possibly cv-qualified) T."
>>
>> Looking up "At" in the scope of the class according to 10.2 will look for
>> declarations of names "At". To me there do not seem to be such
>> declarations.
>
> However, there is a declarationf for At in ``the context of the entire
> postfix-expression''.
>
> If the object expression (the stuff to the left of the dot) is a class,
> then the type name is /ALSO/ looked up in the scope of its class.
> ^^^^^^^
>
> I.e. this class scope lookup is in addition to lookup in the context of
> the expression.
>
> (This is funny wording; in what correct circumstances is the object in a
> member selection postfix expression /not/ of a class type?)
>
Aww, silly me. Now i see. Maybe the Standard has this in mind with the non-
class type?
typedef int A;
int i; i.~A();
But actually, that's not a class member access, but it's a pseudo-
destructor-call (for a class member access, the "A" must be a class-name,
and for the pseudo-dtor-call, the "A" must be of scalar type - which is the
disambiguation used in a postfix-expression). So i'm not sure whether class
member access lookup has to worry about non-class types?
>>
>> However, there is this wording at 10.2/4:
>>
>>
>> "the declaration set, a set of members named f; [...]. In the declaration
>> set, using-declarations are replaced by the members they designate, and
>> type declarations (including injected-class-names) are replaced by the
>> types they designate."
>>
>> Will this allow "At" to be found? And if yes, what will the declaration
>> set contain? The declaration set is said to contain a set of
>> declarations, but how will a *type* fit into such a set? And won't we
>> will first have to find a declaration for "At" to be able to replace it
>> by "N::A" and see that "At" and "N::A" denote the same type?. What is the
>> purpose of that rule?
>
> Declarations aren't textual macros. At actually is the same type from
> which the object a was instantiated; it does not merely typographically
> denote the syntax "N::A".
>
Yes, that's for sure. But name lookup will lexically compare the names if
they are identifiers. So i was wondering: if there is no declaration of the
name "At" in the class, then name lookup for "At" will fail - but comeau and
gcc did not fail, so i was thinking what made them succeed. But i was
missing "At" was in the current scope :)
>> Also, how will access checking proceeed?
>>
>> struct A { };
>> struct B : private A { };
>>
>> int main() { B::A a; }
>
> This is erroneous. The name A is a private member of class scope B,
> and main is not a member funtion of B.
>
Ah, i think i understand now: Even though lookup in classes will never yield
a using declaration as result, access checking can still be influenced by a
using declaration because of the "naming class" thing of 11.2/5). The naming
class is "B" in this example. And "A" as a member of B is private. I think
this is what makes it ill formed. I was deeply confused.
>> If lookup into B for A will replace "B::A" by the declaration ::A (if
>> that is meant by "the type they designate") which is the result of the
>> lookup, then won't this make uses of B::A slip through as valid?
>
> No, because the C++ type system is not a macro processor (at least
> not an unhygienic one).
>
> The expression B::A performs scope resolution, and that is subject
> to access restrictions based on the scope in which it occurs.
>
I see now that my example is weird: There is no reason to replace "A" in A
by "A" in :: - because both are just names that were introduced once into ::
and once into A equally fine, casual by the single lexical declaration (the
"struct A { };" thing).
So a *declaration set* contains a *type* - this is what i find very weird
because the one is a completely different thing from the other. "Name lookup
associates the use of a name with a declaration (3.1) of that name.", but
not with a type (which is an entity). The only thing i could imagine that
could have remotely to do with it is this, to make it valid:
struct A { };
struct B : A { };
struct C : A { };
struct D : B, C { };
D::A a;
It may want to say that any injected class name will be replaced by a
reference to "::A" (but this is of course cursed as said above). But i
wonder whether this can't be done completely without this replacing: D::A
yields a single declaration: the injected class name "A" in class scope A.
Whether there are multiple subobjects is not important for lookup up a type
name. There is no ambiguity even without that special replacing.
Any idea what this replacing is about?
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]