问题描述
下面的代码是用VC ++ 2012编译的:
void f1(void(__stdcall *)())
{}
$ b $ void f2(void(__cdecl *)())
{}
void __cdecl h1()
{}
void __stdcall h2()
{}
int main()
{
f1(h1); //错误C2664
f2(h2); // error C2664
f1([](){}); // OK
f2([](){}); // OK
auto fn = [](){};
f1(fn); // OK
f2(fn); // OK
我认为错误是正常的,但是OK是不正常的。 / p>
所以,我的问题是:
-
如何指定C ++ lambda函数的调用约定?
-
编译器是否自动生成多个版本的lambda函数?即如下面的伪代码:
[] __stdcall(){};
[] __cdecl( ){};在VC ++ 2012上,编译器选择自动调用无状态的转换。
lambda表达式(没有捕获变量)当你将无状态lambda转换为函数指针。 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.
如果调用约定没有定义,如何在调用lambda函数之后正确回收堆栈空间?
:
c $ c> __ stdcall 函数指针。 编辑:
注意:调用转换不在C ++ Standard中,它取决于其他规范,如平台ABI(应用程序二进制接口)。
以下答案基于输出汇编代码,其中。
所以这只是一个猜测,请向微软询问更多细节; P
首先,C ++ lambda(-expression)不是函数(也不是函数指针),你可以像调用普通函数一样调用 operator()给lambda对象。
并且输出汇编代码表示VC ++ 2012通过 __ thiscall 调用转换生成lambda-body
AFAIK,没有办法。 (可能只有 __ thiscall )
可能是
VC ++ 2012 lambda类型提供只有一个lambda-body实现( void operator()()),但为每个调用转换提供了多个用户定义的转换为函数指针 void(__fastcall *)(void), void(__stdcall *)(void)和 void(__cdecl *)(void) type)。
这是一个例子;
//输入源代码
auto lm = [](){/ * lambda-body * /};
//从VC ++ 2012反转C ++代码输出汇编代码
class lambda_UNIQUE_HASH {
void __thiscall operator()(){
/ * lambda-body * /
}
//用户定义的转换
typedef void(__fastcall * fp_fastcall_t)();
typedef void(__stdcall * fp_stdcall_t)();
typedef void(__cdecl * fp_cdecl_t)();
operator fp_fastcall_t(){...}
operator fp_stdcall_t(){...}
operator fp_cdecl_t(){...}
};
lambda_UNIQUE_HASH lm;
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:
On VC++ 2012, compiler choose automatically calling conversion for stateless lambdas (that has no capture variables) when you convert "stateless lambda to function pointer".
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 __thiscall calling 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 with void (__fastcall*)(void), void (__stdcall*)(void), and void (__cdecl*)(void) type).
Here is an example;
// input source code auto lm = [](){ /*lambda-body*/ }; // reversed C++ code from VC++2012 output assembly code class lambda_UNIQUE_HASH { void __thiscall operator()() { /* lambda-body */ } // user-defined conversions typedef void (__fastcall * fp_fastcall_t)(); typedef void (__stdcall * fp_stdcall_t)(); typedef void (__cdecl * fp_cdecl_t)(); operator fp_fastcall_t() { ... } operator fp_stdcall_t() { ... } operator fp_cdecl_t() { ... } }; lambda_UNIQUE_HASH lm;
这篇关于什么是C ++ lambda函数的默认调用约定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!