Closed as duplicate of#82994
Closed as duplicate of#82994
Description
Consider following example (https://godbolt.org/z/cdTfehb3e)
#include <iostream>
#include <string_view>
#define USECONSTEVAL
#ifdef USECONSTEVAL
#define CEXPR consteval
#else
#define CEXPR constexpr
#endif
CEXPR std::string_view name(){
return __PRETTY_FUNCTION__;
}
CEXPR std::string_view name2(){
constexpr auto function = std::string_view(__PRETTY_FUNCTION__);
constexpr static auto value = [] <std::size_t...Idxs>(std::string_view str, std::index_sequence<Idxs...>)
{
return std::array{str[Idxs]..., '\0'};
}(function, std::make_index_sequence<function.size()>{});
static_assert(!std::string_view(value).empty());
return std::string_view(value);
}
template <std::size_t...Idxs>
constexpr auto substring_as_array(std::string_view str, std::index_sequence<Idxs...>)
{
return std::array{str[Idxs]..., '\0'};
}
CEXPR std::string_view name3(){
constexpr auto function = std::string_view(__PRETTY_FUNCTION__);
constexpr static auto value = substring_as_array(function, std::make_index_sequence<function.size()>{});
static_assert(!std::string_view(value).empty());
return std::string_view(value);
}
struct helper {
static constexpr std::string_view value = name();
};
CEXPR std::string_view name4(){
constexpr auto value = helper::value;
return std::string_view{value.data(), value.size()};
}
int main(){
static_assert(not name().empty());
std::cout << "__PRETTY_FUNCTION__: \"" << name() << "\"\n";
static_assert(not name2().empty());
std::cout << "__PRETTY_FUNCTION__: \"" << name2() << "\"\n";
static_assert(not name3().empty());
std::cout << "__PRETTY_FUNCTION__: \"" << name3() << "\"\n";
static_assert(not name4().empty());
std::cout << "__PRETTY_FUNCTION__: \"" << name4() << "\"\n";
}
by toggling the macro USECONSTEVAL
, the output of this sample program changes from
__PRETTY_FUNCTION__: "std::string_view name()"
__PRETTY_FUNCTION__: "std::string_view name2()"
__PRETTY_FUNCTION__: "std::string_view name3()"
__PRETTY_FUNCTION__: "std::string_view name()"
to
__PRETTY_FUNCTION__: "std::string_view name()"
__PRETTY_FUNCTION__: ""
__PRETTY_FUNCTION__: ""
__PRETTY_FUNCTION__: "std::string_view name()"
To the best of my knowledge, there is no reason why consteval
instead of constexpr
should change the meaning of the functions name2
and name3
.
Confusingly, none of the static_assert
that check for emptiness fail, even when the return value is in fact empty.
In case it is relevant, GCC is not affected by this issue, the behavior between constexpr
and consteval
is consistent