Подсказки Visual C ++ constexpr - PullRequest
1 голос
/ 13 июля 2020

Visual C ++ известен тем, что игнорирует квалификаторы функции constexpr, если только это не является абсолютно необходимым. Посмотрите на следующую функцию:

constexpr int multiply(int l, int r) noexcept
{
    return l * r;
}

Согласно стандарту, Visual C ++ полностью разрешено не оценивать rvalue во время компиляции:

auto three_times_four = multiply(3, 4);

Обходной путь, который я использовал using - это уродливая сила:

constexpr auto constexpr_three_times_four = ;
auto not_constexpr_three_times_four = constexpr_three_times_four;
// use not_constexpr_three_times_four in non-constexpr contexts

// alternatively:
template<auto val>
inline constexpr auto ensure_constexpr = val;
auto not_constexpr_three_times_four = ensure_constexpr<multiply(3, 4)>;

Есть ли способ намекнуть компилятору, что эти вещи должны оцениваться во время компиляции?

Меня особенно раздражает следующее :

namespace l
{
    constexpr ::std::uint32_t operator""_crc32(const char * p, ::std::size_t const size) noexcept
    {
        return crc32(p);
    }
}
//...
using namespace l;
search("foo"_crc32);//You don't want to evaluate this at runtime? too bad.

Итак, что я могу сделать, чтобы намекнуть компилятору в этом случае и избежать этих уродливых исправлений?

1 Ответ

6 голосов
/ 13 июля 2020

Не существует механизма, который бы «намекнул» компилятору (любому компилятору), что функция constexpr «должна» быть вызвана во время компиляции. Это не то, что constexpr означает для . Это не инструмент для ускорения выполнения кода. Это инструмент, позволяющий выполнять вычисления, которые имеют , которые должны выполняться во время компиляции.

C ++ 20 позволяет назначать функциям consteval, что гарантирует, что функция должна выполняться внутри постоянного выражения. Но даже эта функция не для производительности; он там, чтобы они могли добавлять новые функции языка (например, значения отражения), которые могут существовать только во время компиляции и не могут проникать в код времени выполнения.

C ++ 20 constinit позволяет вам объявлять не- переменные постоянного выражения, инициализатор которых должен быть постоянным выражением. Это самый близкий C ++ к constexpr -as-a-performance-feature.

Но в противном случае, если более высокие уровни оптимизации компилятора не вызывают эти функции во время компиляции, то компилятор выбрал именно это для реализации функции.

...