Reputation: 3
I'm currently looking for a way to embed the name of a class into the actual objects. Getting the name shouldn't cost anything at runtime. By using the following code i get no additional cost in gcc(since the function is evaluated at compiletime) but for some reason clang doesn't evaluate the code at compiletime
I've tried using different compiler versions but as far as i tested all version of gcc and all version of clang yield the same results (I couldn't really test MSVC since i couldn't find the necessary flags for it to not produce 6K lines of assembly)
#include <string>
#include <string_view>
#include <iostream>
template<class T>
constexpr std::string_view get_name()
{
char const* p = __PRETTY_FUNCTION__;
while (*p++ != '=');
for (; *p == ' '; ++p);
char const* p2 = p;
int count = 1;
for (;;++p2)
{
switch (*p2)
{
case '[':
++count;
break;
case ']':
--count;
if (!count)
return {p, std::size_t(p2 - p)};
}
}
return {};
}
int main(){
std::string_view s = get_name<std::string>();
std::cout << s << std::endl;
}
Clang version: https://godbolt.org/z/_vY8TD
GCC version: https://godbolt.org/z/hhXXWi
I would expect clang to yield a similar result to gcc but that is not the case
Upvotes: 0
Views: 165
Reputation: 66200
The point is that get_name()
is a constexpr
function and you have written
std::string_view s = get_name<std::string>();
and not
constexpr std::string_view s = get_name<std::string>();
In the second case (initialization of a constexpr
variable) the compiler must (almost: ignoring the as-if rule) initialize the s
variable compile-time.
In your case, the execution doesn't depend from run-time known values so the compilers are authorized to choose the compile-time or the run-time execution.
One of they choose to execute compile-time, the other one choose to execute run-time.
Both behaviors are legal.
Upvotes: 1