Closed Yaraslaut closed 2 months ago
Hey @Yaraslaut - Here is what's happening.
form::util::name_of
function returns a std::string
, which necessarily allocates some memory from dynamic storage (i.e., to hold its value).form::util::name_of(^anything)
can never itself be a constant expression (though it may appear in the evaluation of one).form::util::name_of(^T)
in your implementation of constexpr void printMembers()
. The compiler looks to see whether form::util::name_of(^T)
is a subexpression of a larger constant expression, but finds that it isn't one (i.e., because std::println
is not constexpr).constexpr
function of which the call is a part is ill-formed, and "promotes" the function to effectively be consteval
.std::println
is not constexpr. So all it can do is diagnose an error.Based on the above, I believe the issue is with your example - I'm going to close, but please re-open if I've missed something!
Thanks @katzdm for the detailed explanation, I indeed forgot that I changed the signature of name_of
and if i keep string_view than everything is fine, thanks. I am still a bit confused why it is working for declared type, but not for defined through define_class
call
Ah! Good point, and the reason is actually pretty fun - libcxx implements a "short string optimization" in the std::string
implementation, which stores small strings in a static buffer. In the case of the compiler running on godbolt, as many as (but no more than) 22 characters (including the null terminator) can be stored before a dynamic allocation occurs. The name rendered for CreateUniqueT<int, (lambda at /app/example.cpp:96:45)>
is what overruns that 22 character limit, thus triggering a dynamic allocation and rendering the call not-constexpr.
All of that said, there is a subtle bug here: the name returned by name_of
here should just be CreateUniqueT
; the P2996 spec states that name_of
should not include the names of template arguments.
I stumbled in weird compiler error, code in question : https://godbolt.org/z/Yox46WPMd in short