BUG: gcc-2.95 19990609 - namespaces and explicit template specializations

Jonathan Pryor jonpryor@vt.edu
Mon Jun 14 12:28:00 GMT 1999


I've experienced a bug with the gcc-2.95 regarding explicit
template specializations in namespaces.

In a nutshell, if I declare/define a template class within
a namespace, then try to specialize that class using the
`namespace-name::class-name' syntax, the compiler gives
an error.  Sample code and an more in-depth explanation
follow the compiler information.

    gcc version: gcc-2.95 19990609 (prerelease)

    OS Version: Windows NT 4.0 SP4

    compiler binary available at:

ftp://ftp.xraylith.wisc.edu/pub/khan/gnu-win32/cygb20/snapshots/gcc-2.95-199
90609/

    compiler patches:
        Available from the compiler location.
        gcc-2.95-anon-struct-union.diff ... Anonymous structs/unions in C.
        gcc-2.95-c++-anon-struct.diff   ... Anonymous structs in C++.
        gcc-2.95-c++-com1.diff ............ Jason's COM patch.
        gcc-2.95-c++-com2.diff ............ Mumit Khan's tweak for COM.
        gcc-2.95-c++-memfn-refs.diff ...... Jason's VC++ memfn compat.
        gcc-2.95-c++-tidy.diff ............ Jason's C++ "tidying" patch.
        gcc-2.95-libf2c-sysclock.diff ..... Support SYSTEM_CLOCK in WIN32
        gcc-2.95-libgcc2.diff ............. Cross-compilation support.
        gcc-2.95-pragma-pack.diff ......... Mumit Khan's pragma pack patch.
        gcc-2.95-relative-path.diff ....... Cygnus relative pathname patch +
my
                                            tweak.
        gcc-2.95-setasmop.diff ............ Support alias for x86-win32.
        gcc-2.95-stdcall-fix.diff  ........ Fix stdcall FP stack popping
bug.
        gcc-2.95-winnt.diff ............... Hack to support entire classes
from
                                            DLLs in C++.

    patches available from:

ftp://ftp.xraylith.wisc.edu/pub/khan/gnu-win32/cygb20/snapshots/gcc-2.95-199
90609/patches/

    compile line: g++ ns.cpp

Sample Code:

    // ns.cpp - namespace problems?

    namespace foo {
        void bar ();
        template <typename T>
            struct qux {};
    }


    void foo::bar ()
    {
    }


    template<> struct foo::qux<int> {
        static void argh ();
    };


    void foo::qux<int>::argh ()
    {
    }


    int main ()
    {
        return 0;
    }

After trying to compile the sample program, the compiler
generates an error on the line:

    template<> struct foo::qux <int>

The error message reads:

    ns.cpp:15: specializing `struct foo::qux<int>' in different namespace
    ns.cpp:6:   from definition of `template <class T> struct foo::qux<T>'

However, the namespace *is* provided as part of the structure name.

Furthermore, the code in the example is standard-conforming:
>From the standard, section 14.7.3 paragraph 9:

    A template explicit specialization is in the scope of the
    namespace in which the template was defined.
    [Example:
        namespace N {
            template<class T> class X { /* ... */ };
            template<class T> class Y { /* ... */ };

            template<> class X<int> { /* ... */ };  // OK: specialization
                                                    //  in same namespace
            template<> class Y<double>;             // forward declare
intent to
                                                    // specialize for double
        }

        template<> class N::Y<double> { /* ... */ }; // OK: specialization
                                                     //  in same namespace
    --end example]

Workaround: wrap the template specialization with a namespace declaration.
For example, change this:

    template<> struct foo::qux<int> {
        static void argh ();
    };

Into this:

    namespace foo {
        template<> struct foo::qux<int> {
            static void argh ();
        };
    }

 - Jon



More information about the Gcc-bugs mailing list