简体   繁体   中英

“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();
}

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 ?)

To add to the answer of @Ben Voigt, here's an actual working example that runs in no time:

#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();
    //////////////////////////////////////////////

    constexpr auto res = addition(500000);
    std::cout << res;  //500 mill //executes in 0 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();
}

Live Example . Note that I had to shave off a few 0s from your input size. You can tweak this with using the -fconstexpr-steps=N compiler option (for Clang).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM