--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussio...@isocpp.org.
To post to this group, send email to std-dis...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
2015-07-30 20:33 GMT+02:00 Anders Granlund <anders.g...@gmail.com>:
> Yes I forgot the using-directives.
>
> Hmm... interesting. This compiles on both clang and gcc, so that seem to
> suggest that you are correct about type aliases and struct names can denote
> the same entity:
>
> namespace N { struct S {}; }
> namespace M { using S = N::S; }
> using namespace N;
> using namespace M;
>
> int main() { sizeof(S); }
>
> Since S in N and S in M denotes the same entity, the struct type.
>
> The same does not seems to hold for namespaces vs namespace aliases (at
> least not according clang and gcc):
>
> namespace P{ namespace X {} }
> namespace Q { namespace X = P::X; }
> using namespace P;
> using namespace Q;
> namespace P = Q;
> int main() { }
>
> Why this inconsistency?
>
>
I don't know, but perhaps the actual rules are a bit stricter than
what merely that all declarations must declare the same entity.
After
all, name lookup is more than only finding entities. It's about
whether a class-name, typedef-name, etc was found. And 3.4p1 says
"Name lookup shall find an unambiguous declaration for the name (see
10.2). Name lookup may associate more than one declaration with a name
if it finds the name to be a function name;".
As to why typedefs seem to be a special case and compilers don't
complain for them - they and using-declarations seem to be replaced by
their targets and therefore have a special status. At least that
happens for class member name lookup. The spec says for class member
name lookup (which BTW changed from C++03 to C++11 and the popular
compilers don't implement the C++11 rules yet): " 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.".
That the end result of name lookup must still have some notion of
track of where the found declaration came from must be clear. After
all, accessibility checks (which happens after name lookup) must be
able to verify the access path (but how, if the lookup process got rid
of all intermediate declarations!?), and it's beyond me how a "typedef
int haha;" can be replaced by "int" in the declaration set. Perhaps
that's why these rules seem to have stayed unimplemented.
2015-07-30 20:57 GMT+02:00 'Johannes Schaub' via ISO C++ Standard - Discussion <std-dis...@isocpp.org>:2015-07-30 20:33 GMT+02:00 Anders Granlund <anders.g...@gmail.com>:
> Yes I forgot the using-directives.
>
> Hmm... interesting. This compiles on both clang and gcc, so that seem to
> suggest that you are correct about type aliases and struct names can denote
> the same entity:
>
> namespace N { struct S {}; }
> namespace M { using S = N::S; }
> using namespace N;
> using namespace M;
>
> int main() { sizeof(S); }
>
> Since S in N and S in M denotes the same entity, the struct type.
>
> The same does not seems to hold for namespaces vs namespace aliases (at
> least not according clang and gcc):
>
> namespace P{ namespace X {} }
> namespace Q { namespace X = P::X; }
> using namespace P;
> using namespace Q;
> namespace P = Q;Correction: Should have been namespace P = X; instead of namespace P = Q;
> int main() { }
>
> Why this inconsistency?
>
>
I don't know, but perhaps the actual rules are a bit stricter than
what merely that all declarations must declare the same entity.Maybe I missed some special case. I'll check in the standard for that.After
all, name lookup is more than only finding entities. It's about
whether a class-name, typedef-name, etc was found. And 3.4p1 says
I think you are right about that. Actually the same for namespace/namespace aliases. Looking in the standard I see that there are some rules in the standard that rely on weather or not a name is a namespace name or namespace alias name even if they denote the same entity (same namespace). So yes, it seems like the entity denoted isn't everything, there are also the concept of the kind of name we have (typedefname vs class name, namespace alias name vs namespace name). Thanks for your reply, this explains a lot actually.I actually found a special rule about namespace aliases in name-lookup http://eel.is/c++draft/basic.lookup.udir#1:"In a using-directive or namespace-alias-definition, during the lookup for a namespace-name or for a name in a nested-name-specifier only namespace names are considered."Seems like clang and gcc have a bug regarding this. For example they both accept this:namespace P {}namespace X = P;namespace Y = X;int main() {}They both should reject the program since they should not be able to lookup X in namespace Y = X; .
> int main() { }
>
> Why this inconsistency?
>
>
I don't know, but perhaps the actual rules are a bit stricter than
what merely that all declarations must declare the same entity.Maybe I missed some special case. I'll check in the standard for that.After
all, name lookup is more than only finding entities. It's about
whether a class-name, typedef-name, etc was found. And 3.4p1 says
I think you are right about that. Actually the same for namespace/namespace aliases. Looking in the standard I see that there are some rules in the standard that rely on weather or not a name is a namespace name or namespace alias name even if they denote the same entity (same namespace). So yes, it seems like the entity denoted isn't everything, there are also the concept of the kind of name we have (typedefname vs class name, namespace alias name vs namespace name). Thanks for your reply, this explains a lot actually.I actually found a special rule about namespace aliases in name-lookup http://eel.is/c++draft/basic.lookup.udir#1:"In a using-directive or namespace-alias-definition, during the lookup for a namespace-name or for a name in a nested-name-specifier only namespace names are considered."Seems like clang and gcc have a bug regarding this. For example they both accept this:namespace P {}namespace X = P;namespace Y = X;int main() {}They both should reject the program since they should not be able to lookup X in namespace Y = X; .Why not? X is a namespace name. (The standard seems to fail to say that a namespace-alias-definition introduces a namespace-name, but that's clearly the intent; see [namespace.def]p3's reference to "a namespace-name (but not a namespace-alias)", and in any case the phrase "namespace name" is not referencing the grammar term namespace-name, and so can be understood to mean "name that names a namespace").