编译器错误 C7553

lambda 中不支持内联汇编程序

备注

在 Visual Studio 2017 版本 15.9 之前的 Visual Studio 版本中,在 Lambda 中使用内联汇编程序可能会导致 ebp(返回地址寄存器)在运行时损坏。 恶意攻击者可能能够利用此方案。 内联汇编程序只在 x86 上受支持,并且内联汇编程序与编译器的其余部分之间的交互很差。 鉴于这些事实和此问题的本质,此问题的最安全解决方案是,不允许在 Lambda 表达式中使用内联汇编程序。

我们发现“自然情况下”,在 lambda 表达式内使用内联汇编程序的唯一一种情况是用于捕获返回地址。 在此方案中,只需使用编译器内部函数 _ReturnAddress() 即可在所有平台上捕获返回地址。

从 Visual Studio 2017 版本 15.9 开始,Visual Studio 中会出现编译器错误 C7553。

示例

以下代码在 Visual Studio 2017 15.9 和更高版本中生成 C7553:

#include <cstdio>

int f()
{
    int y = 1724;
    int x = 0xdeadbeef;

    auto lambda = [&]
    {
        __asm {  // C7553: inline assembler is not supported in a lambda

            mov eax, x
            mov y, eax
        }
    };

    lambda();
    return y;
}

若要避免该错误,请将程序集代码移动到命名函数中,如以下示例所示:

#include <cstdio>

void g(int& x, int& y)
{
    __asm {
        mov eax, x
        mov y, eax
    }
}

int f()
{
    int y = 1724;
    int x = 0xdeadbeef;
    auto lambda = [&]
    {
        g(x, y);
    };
    lambda();
    return y;
}

int main()
{
    std::printf("%d\n", f());
}