Информация об изменениях

Сообщение Re[8]: constexpr - разочарование от 14.06.2017 8:15

Изменено 14.06.2017 8:17 N. I.

Re[8]: constexpr - разочарование
niXman:

X>эта хотелка уже работает во всех пртестированных мной компиляторах.


Вот только не везде прослеживается связь оптимизации с объявлением функции как constexpr.

https://godbolt.org/g/ZgguUu
https://godbolt.org/g/uITdJo

Если определение функции доступно в каждой единице трансляции, где её вызывают (что типично для шаблонных и inline функций), то ничто не мешает компилятору попробовать вычислить её на этапе компиляции независимо от того, есть у неё спецификатор constexpr или нет. Наличие у функции спецификатора constexpr может лишь дать оптимизатору подсказку, что вероятность существования возможности посчитать её в compile time выше, чем в случае с "обычными" функциями, при этом в общем случае constexpr не даёт гарантий, что функцию можно посчитать в compile time при вызове её с любыми аргументами, значения которых известны на этапе компиляции. Например, здесь

template <typename T>
    constexpr int my_log2(T n)
{
    if (n <= 0)
        std::terminate();
    if (n == 1)
        return 0;
    return 1 + my_log2(n >> 1);
}

int main()
{
    constexpr int x = my_log2(1);
    constexpr int y = my_log2(0);
    std::cout << x << std::endl;
}

существует возможность вычислить my_log2(1) в compile time, но для my_log2(0) такой возможности нет — подобный вызов можно посчитать только в run time, несмотря на то, что в функцию передали вполне себе константный ноль.
Re[8]: constexpr - разочарование
niXman:

X>эта хотелка уже работает во всех пртестированных мной компиляторах.


Вот только не везде прослеживается связь оптимизации с объявлением функции как constexpr.

https://godbolt.org/g/ZgguUu
https://godbolt.org/g/uITdJo

Если определение функции доступно в каждой единице трансляции, где её вызывают (что типично для шаблонных и inline функций), то ничто не мешает компилятору попробовать вычислить её на этапе компиляции независимо от того, есть у неё спецификатор constexpr или нет. Наличие у функции спецификатора constexpr может лишь дать оптимизатору подсказку, что вероятность существования возможности посчитать её в compile time выше, чем в случае с "обычными" функциями, при этом в общем случае constexpr не даёт гарантий, что функцию можно посчитать в compile time при вызове её с любыми аргументами, значения которых известны на этапе компиляции. Например, здесь

template <typename T>
    constexpr int my_log2(T n)
{
    if (n <= 0)
        std::terminate();
    if (n == 1)
        return 0;
    return 1 + my_log2(n >> 1);
}

int main()
{
    constexpr int x = my_log2(42);
    constexpr int y = my_log2(0);
    std::cout << x << std::endl;
}

существует возможность вычислить my_log2(42) в compile time, но для my_log2(0) такой возможности нет — подобный вызов можно посчитать только в run time, несмотря на то, что в функцию передали вполне себе константный ноль.