在调用C函数的其他非抛出内联函数中添加noexcept?

时间:2017-11-13 10:33:45

标签: c++ c++11 noexcept

我为某些C库实现了C ++绑定。库API调用可能会失败,但显然不能抛出任何东西;对于这个问题,我的约束是全部内联的。

现在,对于我的大多数内联函数/方法,编译器可以弄清楚不能抛出异常;例如,假设我有:

bool foo() { 
    auto result = wrapped_lib_foo(); 
    return some_constexpr_nothrow_cond(result); 
}

我应该用noexcept标记这些函数/方法吗?

注意:

2 个答案:

答案 0 :(得分:5)

即使wrapped_lib_fooextern "C"函数,编译器也无法知道堆栈中的某个地方wrapped_lib_foo永远不会抛出,除非您明确告诉它。

然后还有一个事实是,标记函数noexcept会明确告知您的观众该函数不会抛出。

所以是的noexcept是个好主意。

答案 1 :(得分:4)

我认为添加“noexcept”是个好习惯,当你知道某个函数没有抛出时。这是因为如果C函数调用回C ++,它就可以抛出。

是否允许回调C ++和throw,似乎与编译器有关。我检查了两个编译器:

MSVC :有option/EHs,其中:

  

仅捕获C ++异常的异常处理模型   告诉编译器假设声明为extern“C”的函数可以   抛出异常。

因此,如果指定了此选项,则编译器会假定C函数可以抛出。

GCC :这是-fexceptions的文档:

  

启用异常处理。生成传播所需的额外代码   例外。对于某些目标,这意味着GCC会生成帧展开   所有功能的信息,可以产生重要的数据大小   开销,虽然它不会影响执行。如果你没有指定   这个选项,GCC默认为C ++这样的语言启用它   通常需要异常处理,并禁用语言   像C一般不需要它。 但是,您可能需要   在编译需要互操作的C代码时启用此选项   正确使用C ++编写的异常处理程序。你可能也希望   如果要编译没有的旧C ++程序,请禁用此选项   使用异常处理。

因此,这意味着使用-fexceptions,GCC编译可以抛出的C代码。但请注意:在调用C函数时,编译器不知道C代码是否使用-fexceptions编译。所以它必须假设,它是。因此,GCC必须假设似乎,C代码可以抛出(另一种可能的方式可能是需要为C ++代码指定-fexception以告诉编译器被调用C代码可以抛出,但是-fexceptions的文档没有说出这样的内容。)

注意:对于GCC,从涉及C函数的调用堆栈抛出,即使没有当前使用-fexceptions编译的C代码也能正常工作。