Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"constexpr" in C++14

So, as of C++14, the restrictions that constexpr had in C++11 are gone, such as having new variables or loops in the constexpr function.

And the latest versions of the GCC and Clang compilers already support them.

So the issue is this... A constexpr function is computed during compile time and not during execution, as long as the value being passed to it as a parameter is a constant. So the result of the function that I've written below should appear instantaneously during execution, right? But it doesn't.

My question is: why does that happen? And do I have a wrong understanding of C++14's constexpr feature? Thank you.

EDIT: Yes, I was using -OO, that is why it wouldn't work. But setting up -O1 or higher speed optimization does the trick and the program executes as expected. Thank you all for your answers.

#include <iostream>
#include <chrono>

constexpr long long addition(long long num)
{
    long long sum = 0;
    for (int i = 0; i <= num; i++)
    {
        sum += i;
    }

    return sum;
}

int main()
{
    auto start = std::chrono::steady_clock::now();
    //////////////////////////////////////////////

    std::cout << addition(500000000);  //500 mill //executes in 1.957 seconds

    ///////////////////////////////////////////////
    auto stop = std::chrono::steady_clock::now();
    auto dur = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start);
    std::cout << "\n\nIt took " << static_cast<double>(dur.count()) / 1000 << " seconds!";

    std::cin.get();
}
like image 753
DeiDei Avatar asked Sep 16 '15 03:09

DeiDei


1 Answers

A constexpr function is computed during compile time and not during execution, as long as the value being passed to it as a parameter is a constant.

No, the compiler can do so at its discretion, just as with a "pure" function that isn't constexpr. Unless you use it in a context where a compile-time constant is required, such as initialization of a constexpr variable, or use in an array bound (beware VLA g++ extension, though) or as a non-type template argument. For these cases, compile-time evaluation is required. (This is not an exhaustive list: there are other contexts which require compile time constants such as switch case labels, but how do you send a case label value to cout?)

like image 57
Ben Voigt Avatar answered Sep 30 '22 18:09

Ben Voigt