我在使用 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
显式声明此函数不抛出异常,因此编译器将知道此函数调用不会抛出异常,并允许“裸”函数进行编译。