c++11 issue with static constexpr member initializer, constexpr constructor and member function pointer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I'm having an issue using certain c++11 features that gcc should support.
In particular, it seems that gcc has trouble when constexpr constructors
are used with static member initialization using a pointer-to-member
function.

Using compiler flags  -std=3Dc++11 -Wall -pedantic, this code fails to
compile for me using gcc 4.9.1:

template <typename T>
struct Bar
{
    using MemberFuncT =3D int (T::*)();

    MemberFuncT h_;
    constexpr Bar(MemberFuncT h) : h_{h}
    {
    }
};

struct Foo
{
    int test()
    {
        return -1;
    }

    // this causes the brace-enclosed initializer error message:
    static constexpr Bar<Foo> bar =3D Bar<Foo>(&Foo::test);

    // but this line does not:
    // static constexpr Bar<Foo> bar =3D Bar<Foo>(nullptr);

    // this line also causes the error message, unless you remove the
    // explict constructor in Bar.
    // static constexpr Bar<Foo> bar =3D {&Foo::test};
};

constexpr Bar<Foo> Foo::bar;

// the line below does not cause any problems, either:
// static constexpr Bar<Foo> bar =3D Bar<Foo>(&Foo::test);

int main(void)
{
    Foo f;
    return (f.*(Foo::bar.h_))();
}

When I attempt to compile the above program, I get

bug.cpp:22:56: error: =E2=80=98const Bar<Foo>{&Foo::test}=E2=80=99 is not a=
 constant
expression
     static constexpr Bar<Foo> bar =3D Bar<Foo>(&Foo::test);

But my best reading of the standard indicates that this should indeed be a
constant expression. It compiles without errors on clang 3.6 rc2. You can
also see several experiments that I did to try to narrow down the scope of
the issue (commented out). I also tried using a pointer to a free function,
and it compiled cleanly with gcc 4.9.

>From these experiments, it seems that the problem only occurs when the
following conditions are met:

- initializing a static constexpr class member
- the class member has an explicit constexpr constructor
- the class member constructor takes a pointer-to-member function

Here is the output of gcc -v

Using built-in specs.
COLLECT_GCC=3Dgcc
COLLECT_LTO_WRAPPER=3D/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion=3D'Ubuntu
4.9.1-16ubuntu6' --with-bugurl=3Dfile:///usr/share/doc/gcc-4.9/README.Bugs
--enable-languages=3Dc,c++,java,go,d,fortran,objc,obj-c++ --prefix=3D/usr
--program-suffix=3D-4.9 --enable-shared --enable-linker-build-id
--libexecdir=3D/usr/lib --without-included-gettext --enable-threads=3Dposix
--with-gxx-include-dir=3D/usr/include/c++/4.9 --libdir=3D/usr/lib --enable-=
nls
--with-sysroot=3D/ --enable-clocale=3Dgnu --enable-libstdcxx-debug
--enable-libstdcxx-time=3Dyes --enable-gnu-unique-object
--disable-vtable-verify --enable-plugin --with-system-zlib
--disable-browser-plugin --enable-java-awt=3Dgtk --enable-gtk-cairo
--with-java-home=3D/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64/jre
--enable-java-home
--with-jvm-root-dir=3D/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64
--with-jvm-jar-dir=3D/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-amd64
--with-arch-directory=3Damd64 --with-ecj-jar=3D/usr/share/java/eclipse-ecj.=
jar
--enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=3Di686
--with-abi=3Dm64 --with-multilib-list=3Dm32,m64,mx32 --enable-multilib
--with-tune=3Dgeneric --enable-checking=3Drelease --build=3Dx86_64-linux-gn=
u
--host=3Dx86_64-linux-gnu --target=3Dx86_64-linux-gnu
Thread model: posix
gcc version 4.9.1 (Ubuntu 4.9.1-16ubuntu6)

I tried creating an account on the bugzilla in order to report this, but it
rejects my email address for some reason. Are gmail.com addresses blocked?

-- 
Bobby Moretti
bobmoretti@xxxxxxxxx




[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux