c++11 issue with static constexpr member initializer, constexpr constructor and member function pointer
Bobby Moretti
bobmoretti@gmail.com
Tue Apr 7 21:51:00 GMT 2015
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@gmail.com
More information about the Gcc-help
mailing list