我在使用 Visual Studio 15 编译某些东西时遇到了问题。这段代码说明了这一点:

const char* getx() { return "foo"; }

void __declspec(naked) nf()
{
    static const char* x = getx();
}

这失败并出现以下错误: Error C3068 'nf': a 'naked' function cannot contain objects that would require unwinding if a C++ exception occurred 。不过,我真的不明白为什么会失败;静态对象不是自动的,就存储而言,它们的行为或多或少类似于全局对象,并在执行入口点之前进行初始化(据我所知)。如果是这样,那么这条消息指的是什么展开?此时堆栈上没有任何内容,因此没有什么可放松的。此外,如果我删除函数调用, static 变量声明就可以了(没有赋值的函数调用也是如此,或者为 x 变量分配一个常量值,例如 static const char* x = 0; )。

我在这里遗漏了什么吗?

最佳答案

C++11 中引入的 noexcept 函数属性正式声明该函数不会抛出异常。

即使 getx() 可能不会抛出异常,编译器也不会自动添加 noexcept 属性,因为这会更改函数签名。

因此,当编译器解析 nf() 函数时,它会看到对另一个可能抛出异常的函数的调用,这显然在特定于平台的“裸”函数中是被禁止的。

getx 显式声明为 noexcept 显式声明此函数不抛出异常,因此编译器将知道此函数调用不会抛出异常,并允许“裸”函数进行编译。

10-08 09:15