On 26/02/2021 15:17, Bonita Montero wrote:
> Lambdas with no captures can be handled like ordinary functions and you
> can get the address of the lambda as a normal function-pointer. AFAIK
> there's no compiler which allows to specify a callig-convention on a
> lambda. But with MSVC you can convert a lamda to a function-pointer of
> any type, i.e. you can convert it to __cdecl, __fastcall or whatever
> (they exist for x86 only, x64 has a consistent calling convention for
> all calls). What MSVC does here is that it compiles the lambda multiple
> times for each calling convention on demand.
>
Calling conventions - especially the various ones supported by MSVC -
are very much implementation specific. On most platforms you have a
single ABI that all compilers adhere to, but not on 32-bit Windows. So
how different calling conventions are handled on Win32 will be entirely
up to the compiler.
Lambdas have internal linkage and are usually not "exported" in any way,
so compilers are free to use whatever calling conventions they want -
there is no need for any consistency, especially if the lambda is a leaf
function.
When you convert a lambda to a pointer-to-function, you are actually
using a conversion function template which is free to give different
results for different pointer types. (It can even give different
results for the same pointer types, although that would be less likely
in a real implementation.)
See the section on "ClosureType::operator ret(*)(params)()" :
<
https://en.cppreference.com/w/cpp/language/lambda>
Of curiosity, what happens if you replace the lambda with a static function:
static auto lambda(string str) { cout << str << endl; }
?