This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/65695] [4.9/5 Regression] NSDMI calling constexpr constructor with pointer-to-member is not a constant expression
- From: "jaehnesn at gmx dot de" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 10 Apr 2015 10:50:33 +0000
- Subject: [Bug c++/65695] [4.9/5 Regression] NSDMI calling constexpr constructor with pointer-to-member is not a constant expression
- Auto-submitted: auto-generated
- References: <bug-65695-4 at http dot gcc dot gnu dot org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65695
Sebastian JÃhne <jaehnesn at gmx dot de> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jaehnesn at gmx dot de
--- Comment #4 from Sebastian JÃhne <jaehnesn at gmx dot de> ---
(In reply to Jonathan Wakely from comment #0)
> From https://gcc.gnu.org/ml/gcc-help/2015-04/msg00034.html
>
> template <typename T>
> struct Bar
> {
> using MemberFuncT = 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 = Bar<Foo>(&Foo::test);
>
> // but this line does not:
> // static constexpr Bar<Foo> bar = Bar<Foo>(nullptr);
>
> // this line also causes the error message, unless you remove the
> // explict constructor in Bar.
> // static constexpr Bar<Foo> bar = {&Foo::test};
> };
>
> constexpr Bar<Foo> Foo::bar;
>
> // the line below does not cause any problems, either:
> // static constexpr Bar<Foo> bar = Bar<Foo>(&Foo::test);
>
> int main(void)
> {
> Foo f;
> return (f.*(Foo::bar.h_))();
> }
>
> c.cc:20:56: error: âBar<Foo>{&Foo::test}â is not a constant expression
> static constexpr Bar<Foo> bar = Bar<Foo>(&Foo::test);
> ^
>
> Clang and EDG accept the code.
If you change your code in the following manner, it works:
template <typename T>
struct Bar
{
using MemberFuncT = int (*)();
MemberFuncT h_;
constexpr Bar(MemberFuncT h) : h_{h}
{
}
};
struct Foo
{
static int test()
{
return -1;
}
static constexpr Bar<Foo> bar = Bar<Foo>(&Foo::test);
};
constexpr Bar<Foo> Foo::bar;
int main(void)
{
Foo f;
return (f.bar.h_)();
}
You shouldn't be able to declare a static variable which has access to a
non-static member function. I would call this a bug in CLANG and EDG.