Why are there differences between compiled C ++ 17 lambas between GCC and clang?

This is reproduced on GCC 7.1 and clang 4.0. As well as both snapshots on July 30, 2017.

Example 1: Calling lambdas other than the return statement, both compilers behave differently.

int main()
{
    auto sum = [](auto ... a) { return (... + a); };

    auto value1{sum(5,5)};   // Having optimization disabled -O0,
                             // GCC treats this line as if constexpr is there,
                             // clang doesn't.

    constexpr auto value2{sum(1,2,3,4)};  // Both treat this line as constexpr like expected.

                            // As a result, in GCC, no trace of lambdas in the executable,
                            // and only one lambda in clang.

    return value1 + value2;
}

      

Live @godbolt

Example 2 and 3: Calling lambdas in a return statement, both compilers behave the same: runtime estimate / no constexpr.

int main()
{
    auto sum = [](auto ... a) { return (... + a); };

    return sum(5,5) + sum(1,2,3,4);   // Both compilers generate 2 lambdas like expected.

}

      

Live @godbolt

int main()
{
    constexpr auto sum = [](auto ... a) { return (... + a); };

    return sum(5,5) + sum(1,2,3,4);   // Both compilers generate 2 lambdas like expected.

}

      

Live @godbolt


Does the standard body support this between compilers? Why?

+3


source to share


1 answer


A lambdas call other than a return statement behaves differently in both compilers.

They can output different assemblies, but they have the same behavior. This is what the Standard guarantees, nothing else. So both are correct in this respect, since they both return 20

.

constexpr

expressions do not need to be evaluated at compile time, if possible. There is nothing that prevents implementations from calling add

instead of optimizing in the following example:



constexpr int add(int lhs, int rhs) {
    return lhs + rhs;
}

int main() {
    return add(4, 5);
}

      

They can, but that doesn't mean they should. The standard tries to give the implementation as much freedom as possible when compiling to allow, for example, strong optimizations, which is partly the reason for undefined behavior and things like poorly formed; no need for diagnostics (correct me if i'm wrong).

Note that compiling with -O3

results in both compilers returning 20

in your three examples, so there is no difference.

+4


source







All Articles