【发布时间】:2013-01-28 12:51:48
【问题描述】:
以下代码使用 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
}
我认为错误是正常的,但 OK 是异常的。
所以,我的问题是:
C++ lambda 函数的调用约定是什么?
如何指定 C++ lambda 函数的调用约定?
如果没有定义调用约定,如何在调用lambda函数后正确回收堆栈空间?
-
编译器会自动生成多个版本的 lambda 函数吗?即如下伪代码:
[] __stdcall (){};
[] __cdecl (){};等等
【问题讨论】:
-
链接这个问题似乎很有用:stackoverflow.com/questions/14169295/…
-
f1使用的是__stdcall,但h1使用的是__cdecl;如果你交换它们,它会起作用吗? -
由于 C++ 标准没有提及任何关于调用约定的内容,因此您的第一个问题的答案似乎是编译器特定的。
-
我认为@jogojapan 链接的问题回答了这个问题。查看发布在其中的符号转储,当您定义 lambda 时,似乎 VC 会生成具有所有 3 种调用约定的函数调用运算符。它将根据调用 lambda 的方式链接最合适的匹配项。
-
@jogojapan,很抱歉我忽略了您提供的链接。我已为您的评论点赞并删除了我的第一条评论。
标签: c++ function c++11 lambda calling-convention