Почему эта функция оценивается во время компиляции в g ++, а не в clang ++ - PullRequest
0 голосов
/ 24 декабря 2018

В настоящее время я ищу способ встраивания имени класса в реальные объекты.Получение имени не должно ничего стоить во время выполнения.Используя следующий код, я не получаю никаких дополнительных затрат в gcc (поскольку функция оценивается во время компиляции), но по какой-то причине clang не оценивает код во время компиляции

Я пытался использовать разные версии компилятора, но какПоскольку я тестировал все версии gcc и все версии clang, они давали одинаковые результаты (я действительно не смог протестировать MSVC, так как не смог найти необходимые флаги, чтобы он не производил 6K строк сборки)

#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: https://godbolt.org/z/_vY8TD

Версия GCC: https://godbolt.org/z/hhXXWi

Я ожидаю, что clang даст аналогичный результат для gcc, но это не так

1 Ответ

0 голосов
/ 24 декабря 2018

Дело в том, что get_name() является функцией constexpr, и вы написали

 std::string_view s = get_name<std::string>(); 

, а не

 constexpr std::string_view s = get_name<std::string>(); 

Во втором случае (инициализация constexpr переменная) компилятор должен (почти: игнорируя правило as-if) инициализирует s переменную времени компиляции.

В вашем случае выполнение не зависит от выполнения-время известных значений, чтобы компиляторы имели право выбирать время компиляции или выполнения во время выполнения.

Одно из них выбирает выполнение времени компиляции, другое выбирает выполнение времени выполнения.

Оба поведения являются законными.

...