The following code was compiled with VC++ 2012:
void f1(void (__stdcall *)())
{}
void f2(void (__cdecl *)())
{}
void __cdecl h1()
{}
void __stdcall h2()
{}
int main()
{
f1(h1); // error C2664
f2(h2); // error C2664
f1([](){}); // OK
f2([](){}); // OK
auto fn = [](){};
f1(fn); // OK
f2(fn); // OK
}
I think the errors are normal yet the OKs are abnormal.
So, my questions are:
-
What’s the calling convention of a C++ lambda function?
-
How to specify the calling convention of a C++ lambda function?
-
If the calling convention is not defined, how to correctly recycle the stack space after having called a lambda function?
-
Does the compiler automatically generate multiple versions of a lambda function? i.e. as the following pseudo-code:
[] __stdcall (){};
[] __cdecl (){}; etc.
On VC++ 2012, compiler choose automatically calling conversion for stateless lambdas (that has no capture variables) when you convert "stateless lambda to function pointer".
MSDN C++11 Features:
EDITED:
NB: The calling conversion is out of C++ Standard, it depends on other specification such as platform ABI(application binary interface).
The following answers are based on output assembly code with /FAs compiler option.
So it’s a mere guess, and please ask Microsoft for more detail ;P
First of all, C++ lambda(-expression) is NOT a function (nor function pointer), you can call
operator()to lambda object like a calling normal function.And output assembly code says that VC++ 2012 generates lambda-body with
__thiscallcalling conversion.AFAIK, there is no way. (It may be only
__thiscall)Probably No.
The VC++ 2012 lambda-type provides only one lambda-body implementation (
void operator()()), but provides multiple "user-defined conversion to function pointer" for each calling conversion (operator return function pointer withvoid (__fastcall*)(void),void (__stdcall*)(void), andvoid (__cdecl*)(void)type).Here is an example;