禁用异常支持是否也禁用对`std :: move_if_noexcept`的支持?

时间:2014-12-08 23:04:33

标签: c++ exception c++11 move-semantics

某些商店(例如某些视频游戏开发团队)会在其构建环境中禁用对异常的支持。在禁用异常的情况下,开发人员没有理由声明他们的移动操作noexcept(假设这样的代码甚至可以编译)。但是标准库实现应该在实现某些操作时调用std::move_if_noexcept(例如,std::vector::push_back)。标准库实现通常在编译期间检查以查看是否禁用了异常,如果是,请使用std::move而不是std::move_if_noexcept?当禁用异常时,编译器会导致std::is_nothrow_move_constructible为所有类型返回true吗?或者,禁用对异常的支持是否会导致std:move_if_noexcept无法启用移动操作的意外副作用?

我对实践中发生的事情很感兴趣。我知道禁用对异常的支持使我们脱离了C ++标准的范畴。

2 个答案:

答案 0 :(得分:3)

此代码在GCC 4.9和clang 3.5上输出false true false true,启用或不启用异常:

void foo() {}
void bar() noexcept {}
void foo2() noexcept(noexcept(foo())) {}
void bar2() noexcept(noexcept(bar())) {}

int main() {
    std::cout << std::boolalpha << noexcept(foo()) << ' ' << noexcept(bar())
        << ' ' << noexcept(foo2()) << ' ' << noexcept(bar2()) << std::endl;    
}

Demo

所以看起来noexcept行为至少对这两个编译器来说并不依赖于编译器选项。

更新:VS2013 doesn't support noexcept at all

答案 1 :(得分:0)

  

-fnothrow-OPT   将throw()异常规范视为noexcept规范,以减少或消除文本大小开销   相对于没有异常规范的函数。如果   函数具有带有非平凡析构函数的局部变量,   异常规范实际上使函数变小   因为可以优化那些变量的EH清理。该   语义效果是一个异常抛出的函数   这样的异常规范会导致调用终止   比意想不到的。

所以根据gcc文档,throw函数变成noexcept规范。

这应该意味着更多的对象将返回true而不是