我在使用Visual Studio 15编译时遇到了问题.此代码说明了这一点:
const char* getx() { return "foo"; }
void __declspec(naked) nf()
{
static const char* x = getx();
}
这失败并出现以下错误:错误C3068’nf’:’naked’函数不能包含在发生C异常时需要展开的对象.不过,我真的不明白为什么会失败;静态对象不是自动的,就存储而言,它们的行为或多或少类似于全局变量,并且在执行入口点之前被初始化(据我所知).如果是这样,那么这条消息指的是什么?此时堆栈上什么都没有,所以没什么可放松的.另外,如果我删除函数调用,静态变量声明就可以了(没有赋值的函数调用,或者为x变量赋值,例如static const char * x = 0;).
我在这里错过了什么吗?
最佳答案 在C 11中引入的noexcept函数属性正式声明该函数不会抛出异常.
即使getx()不能抛出任何异常,编译器也不会自动添加noexcept属性,因为这会更改函数签名.
因此,当编译器解析nf()函数时,它会看到对另一个可能抛出异常的函数的调用,这显然是在特定于平台的“裸”函数中被禁止的.
明确声明getx为noexcept显式声明此函数不会抛出异常,因此编译器将知道此函数调用不会抛出异常,并允许“naked”函数进行编译.