https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101557
Bug ID: 101557 Summary: the value of '<temporary>' is not usable in a constant expression Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: federico.kircheis at gmail dot com Target Milestone: --- Consider following snippet ---- struct node { const char* d; const node& left; const node& right; }; constexpr const node Null = node{"",Null,Null}; constexpr const node a { "a", node { "b", node{"e",Null,Null}, node{"d",Null,Null}, }, node{"c",Null,Null}, }; constexpr int mysize(const node& n) noexcept{ return (&n == &Null) ? 0 : 1 + mysize(n.left) + mysize(n.right); } constexpr auto size0 = mysize(Null); static_assert(size0 == 0, ""); constexpr auto size1 = mysize(node{"c", Null, Null}); static_assert(size1 == 1, ""); constexpr auto size2 = mysize(node { "b", node{"e",Null,Null}, node{"d",Null,Null}, }); static_assert(size2 == 3, ""); // this line does not compile constexpr auto size3 = mysize(a); static_assert(size3 == 5, ""); ---- The expression `constexpr auto size3 = mysize(a);` does not compile with the error message ---- <source>:41:30: in 'constexpr' expansion of 'mysize(a)' <source>:25:42: in 'constexpr' expansion of 'mysize((* & n.node::left))' <source>:41:32: error: the value of '<temporary>' is not usable in a constant expression 41 | constexpr auto size3 = mysize(a); | ^ <source>:22:1: note: '<temporary>' was not declared 'constexpr' 22 | }; | ^ Compiler returned: 1 ---- A similar effect can be achieved with ---- constexpr node b = a.left; ---- with following error ---- <source>:45:23: error: the value of '<temporary>' is not usable in a constant expression 45 | constexpr node b2 = a.left; | ^~~~ <source>:22:1: note: '<temporary>' was not declared 'constexpr' 22 | }; | ^ Compiler returned: 1 ---- even if ---- constexpr node b = a; ---- compiles without warnings. Generally accessing subobjects should not be an issue, for example ---- struct sub{}; struct node2{ const sub& s; }; constexpr const node2 n2{ sub{} }; constexpr auto s = n2.s; ---- also compiles without issues