[cfe-dev] [C++11] a question involving forward declarations for enums

Richard Smith richard at metafoo.co.uk
Mon Apr 1 14:57:27 PDT 2013


On Mon, Apr 1, 2013 at 10:42 AM, John McCall <rjmccall at apple.com> wrote:

> On Mar 31, 2013, at 11:53 PM, ZhangXiongpang <zhangxiongpang at gmail.com>
> wrote:
> > Platform: linux, x86_64, clang++3.2, g++4.7.2
> >
> > See the following code:
> > ------------------------------------------
> > namespace M {
> >    namespace N {
> >        enum class E; // #1
> >    }
> >    using N::E;       // #2
> > }
> > enum class M::E { e1, e2 }; // #3
> > M::E e; // clang++ reports ambiguous
> > ------------------------------------------
> > g++ treats #3 as a defination of M::N::E, while clang++ treats it as a
> > defination of M::E
> >
> > I saw paragraph 4 in [dcl.enum]:
> > ------------------------------------------
> > "If the enum-key is followed by a nested-name-specifier, the
> enum-specifier
> > shall refer to an enumeration that
> > was previously declared directly in the class or namespace to which the
> > nested-name-specifier refers (i.e.,
> > neither inherited nor introduced by a using-declaration), [...]"
> > ------------------------------------------
> >
> > So I think it is obvious that g++ does not obey C++ standard.
> > But I'm not sure whether clang++ strictly obey the standard.
> > My understanding of the standard's description has double meanings:
> > ------------------------------------------
> > (1) the enum-specifier shall refer to an enumeration that was previously
> > declared directly in the namespace
> > (2) the enum-specifier shall refer to an enumeration that was not
> introduced
> > by a using-declaration
> > ------------------------------------------
> > And the (1) make me confused, I'm not sure whether the
> using-declaration(#2)
> > implies a opaque-enum-declaration of E in namespace M.
> > If not, then perhaps clang++ shall report error when parsing #3.
> > Is my understanding right?
>
> I agree;  neither compiler is correct here.


Class types have the same rule (see [class]p11) and we don't enforce that
either. For instance:

namespace M {
  namespace N {
    struct S;
  }
  using N::S;
}
struct M::S { };
M::S m; // error, ambiguous

FWIW, g++ accepts both of these (even with -pedantic) and EDG accepts both
outside its strict mode.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130401/df7feb38/attachment.html>


More information about the cfe-dev mailing list