Search code examples
c++c++11lambdalanguage-lawyer

Can Different Lambdas Decay to the Same Function Pointer?


Can two different lambdas (that have no capture, and the same args and body) decay to the same function pointer?

I have this code:

#include <cassert>
#include <type_traits>

int main() {
    auto f0 = [](auto x) { return x; };
    auto f1 = [](auto x) { return x; };
    
    static_assert(not std::is_same_v<decltype(f0), decltype(f1)>);

    // MSVC Release-mode combines the functions so the pointers are the same (even though the types should be different.
    assert(static_cast<int(*)(int)>(f0) != static_cast<int(*)(int)>(f1));
}

https://godbolt.org/z/P3vc45654

I believe the static_assert is guaranteed to pass. Is that assert guaranteed to pass? (I'm seeing MSVC in release mode failing the assert on my computers.)


Solution

  • I have to disagree with the existing answers.

    You're not using the function call operator. You're using the conversion to "pointer to function". Since your lambdas have auto parameters, they're generic lambdas.

    The conversion to "pointer to function" in this case is described as follows (N4950, [expr.prim.lambda.closure]/9):

    For a generic lambda with no lambda-capture, the closure type has a conversion function template to pointer to function. The conversion function template has the same invented template parameter list, and the pointer to function has the same parameter types, as the function call operator template. The return type of the pointer to function shall behave as if it were a decltype-specifier denoting the return type of the corresponding function call operator template specialization.

    Nothing here says anything about creating pointers to unique functions, or anything similar.

    Microsoft's implementation does not seem to violate any rules here.