8

Consider the following simplified code:

template <class T> class Foo { T t; const T* t_ptr; public: constexpr Foo(T t): t(t), t_ptr(&this->t) {} constexpr Foo(const Foo& foo): t(foo.t), t_ptr(&this->t) {} constexpr T get_t() const { return *t_ptr; } }; template <class T> constexpr Foo<T> foo(T t) { return Foo<T>(t); } constexpr auto f = foo(1); static_assert(f.get_t() == 1); 

It successfully compiles with Clang and MSVC but GCC 15 gives an error:

<source>:16:25: error: non-constant condition for static assertion 16 | static_assert(f.get_t() == 1); | ~~~~~~~~~~^~~~ <source>:16:22: in 'constexpr' expansion of 'f.Foo<int>::get_t()' <source>:8:17: error: the value of 'f' is not usable in a constant expression 8 | return *t_ptr; | ^~~~~ <source>:15:16: note: 'f' used in its own initializer 15 | constexpr auto f = foo(1); | ^ Compiler returned: 1 

Is this code valid? Is this a bug in GCC? Is there a workaround to make constexpr structs that contain a pointer to its own member work?

1

1 Answer 1

7

I think it is a gcc bug.

Some variants pass when calling constructors directly Demo

I think gcc badly implements the note from copy_elision (code "similar" to yours).

In constant expression and constant initialization, copy elision is never performed.

Sign up to request clarification or add additional context in comments.

2 Comments

Does anyone know if this bug is already reported on the GCC Bugzilla or if the GCC developers are aware of it?
Nothing changes in any of compilers, if copy constructor is deleted constexpr Foo(const Foo& foo) = delete; gcc.godbolt.org/z/KGd6jzM4f

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.