Nevermind my last reply reffering to (See [std-discussion] Inconsistency
between structs and functions when defining them via using-declaration). *Here
comes the correct reply:*
I just realised one thing now and it indicates *a bug in clang*. The
following example you gave (the same hold for you other example also, but
lets take one of them to be concrete) *is actually ill-formed:*
struct S;
namespace N { using ::S; }
struct N::S {};
I'll explain later in the reply why it is ill-formed. It compiles however
on clang (just as you said earlier), so this seems to indicate a bug in
clang.
Your point about using-declaration not beeing opaque to redeclaration is
still correct however (this is because as you say that qualified
definitions of namespace members works like normal qualified lookup in
terms of finding the target declaration that we are redeclaring with the
definition. And also because qualified name lookup propagates via
using-delcarations). The first example you gave can be saved like this:
namespace P {
struct S;
}
namespace N {
using P::S;
}
struct N::S {};
Now it is well-defined, and still proves your point.
Now, why is your original example ill-formed? Well the reason is simple:
struct N::S {}; is a qualified namespace member definition and it is a
redeclaration of struct S; just as you said earlier yourself. However this
is the problem. Remember that there are only two ways of defining a
namespace member:
* Either you use an *unqualified* definition in the declarative region of
the namespace. (We don't have this case here since we have a qualified
instead of an unqualified namespace member definition here):
This case is [namespace.memdef]p1 in the c++ standard:
http://eel.is/c++draft/namespace.memdef#1
* Or you use a *qualified* definition *outside *the namespace *in an
enclosing namespace . *We almost have this case in your example, but the
problem is that the qualified namespace member definition struct N::S {}; is
in the *same* namespace (the global namespace) as struct S; and *not
outside it in an enclosing namespace *(not even possible since the global
namespace is the outermost one).
This case is [namespace.memdef]p2 in the c++ standard:
http://eel.is/c++draft/namespace.memdef#2
See the discussion "[std-discussion] Qualified definition of namespace
member in the same namespace as the declaration" for something similar, but
in that case a normal namespace instead of the global namespace and no
middle landing in another namespace in the qualified name-lookup. Otherwise
the same.
Do you agree?
Post by David RodrÃguez IbeasPost by Richard SmithPost by Anders GranlundThanks for the clarification. I thought it would be a good idea to try
to find compiler bugs by investigating edge cases in the standard, but it
seems like i'm just finding standard defects/ambiguities that way. I'm a
bit chocked about how ambiguous the c++ standard is. Seems to be a lot of
issues reported. I have some questions on stack overflow. I guess most of
them is answered by some c++ standard issue.
If I understand everything correctly. Because of 1838, the following
programs (taken from 1021) should also be ill-formed for the same reason?
The second of them I have actually tried earlier, and it compiles on GCC,
Clang and MSVS, and as you say both of them compiles on major compilers.
namespace N {
struct A;
}
using N::A;
struct A { };
int main() {}
struct S;
namespace A {
using ::S;
struct S { };
}
int main() {}
So this means that the compilers needs to be fixed to emit a diagnostic message for these situations?
Yes; Clang trunk now rejects both of these.
I guess we can conclude that using-declarations should be opaque when it comes to redeclarations, ie redeclarations doesn't work at all via using-declarations?
struct S;
Post by Richard Smithnamespace N { using ::S; }
struct N::S {};
extern int n;
namespace N { using ::n; }
int N::n;
Aren't the programs above ill-formed according to the c++ standard? (See [std-discussion]
Inconsistency between structs and functions when defining them via
using-declaration)
Post by Richard SmithGCC accepts this, Clang and EDG reject. MSVC crashes.
The idea, last time we discussed this in CWG, was that unqualified
(non-template-id) non-block-scope declarations always declare the entity to
be within the current namespace/class, and qualified declarations (and
template-ids) are always looked up and must find some existing entity (and
must be in a namespace enclosing that entity's namespace). I don't think
that really answers how these new cases should behave, though.
I guess we also could conclude that redeclarations can never be made across different declarative regions?
Post by Richard SmithPost by Anders GranlundPost by Richard SmithPost by Anders GranlundAccording to my current understanding of the c++ standard, the
namespace X {
class A;
}
namespace Y {
using X::A;
class A {};
}
int main() {}
Visual studios c++ compiler does not agree with me on this. When
error C2888: 'X::A': symbol cannot be defined within namespace 'Y'
Looking at the description of error C2888 at
https://msdn.microsoft.com/en-us/library/27zksbks.aspx it looks like
they are referring to the following rule of the c++ standard,
Members of a named namespace can also be defined outside that
namespace by explicit qualification ([namespace.qual]) of the name being
defined,
provided that the entity being defined was already declared in the
namespace and the definition appears after the point of declaration in a
namespace
that encloses the declaration's namespace.
My example program is not violating this rule however, since i'm not
even using explicit qualification when I define the class A.
Is there any other rule of the standard that I have missed that my
example program is violating?
See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1838,
which replaces the words you referenced above. [That issue (and its wording
change) doesn't apply to class declarations, but it was intended to -- see
the reference to
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1021
which is marked as also being resolved by 1838. I've filed a core issue to
get the wording here tweaked to actually address issue 1021.]
Under issue 1838, because 'class A' in namespace Y is declared with an
unqualified name, it declares a member of Y, rather than redeclaring X::A.
there are two different entities named A within namespace Y.
--
---
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
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.
To unsubscribe from this group and stop receiving emails from it, send
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.
To unsubscribe from this group and stop receiving emails from it, send an
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.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-discussion/.