C++ 如果没有异常,禁用对异常的支持是否也会禁用对“std::move”的支持?

C++ 如果没有异常,禁用对异常的支持是否也会禁用对“std::move”的支持?,c++,exception,c++11,move-semantics,C++,Exception,C++11,Move Semantics,一些商店(例如,一些视频游戏开发团队)在其构建环境中禁用对异常的支持。如果禁用了异常,开发人员就没有理由声明他们的移动操作noexcept(假设这样的代码甚至可以编译)。但标准库实现在实现某些操作(例如,std::vector::push_)时,如果没有异常,则应该调用std::move\u。标准库实现是否通常在编译期间检查异常是否被禁用,如果禁用,则使用std::move,而不是std::move_if_noexcept?当异常被禁用时,编译器是否会导致所有类型的std::is_nothrow

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


我对实践中发生的事情很感兴趣。我理解禁用异常支持C++将我们排除在C++标准之外。< /P> < P>在GCC 4.9和CLAN 3.5上输出代码< >代码>假真假< /C> >启用或不启用异常:< /P>
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;    
}
void foo(){}
void bar()不例外{}
void foo2()noexcept(noexcept(foo()){}
void bar2()noexcept(noexcept(bar()){}
int main(){
标准::cout
-fnothrow opt
将throw()异常规范视为noexcept规范来减少或消除文本大小开销
相对于没有异常规范的函数。如果
函数具有非平凡析构函数类型的局部变量,
异常规范实际上使函数更小
因为这些变量的EH清理可以优化掉
语义效果是从函数中抛出一个异常
这样的异常规范导致调用终止,而不是终止
而不是出乎意料

因此,根据gcc文档,抛出函数成为noexcept规范


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

这不是很容易为自己测试吗?@KerrekSB:我当然可以为自己测试我可以访问的编译器,但我可以访问的编译器数量有限,我想在通常禁用异常的环境中工作的人应该已经知道了答案。至于是否“容易”为了测试…需要对标准库实现进行一些清理,以了解发生了什么,这并不总是简单的工作。libc++和libstdc++似乎都对编译器是否禁用异常不感兴趣,因此您不会神奇地让所有移动都成为那些库中的移动。像
std::这样的特性是_nothrow_可构造的
是用
noexcept
运算符表示的,它通常与环境是否实际支持异常无关。就特性而言,它只是函数声明的抽象部分。虽然看起来不是这样,但它看起来确实像编译器应该含蓄地使一切都“不例外”无论何时禁用异常。对于大多数编译器供应商来说,这应该是一个非常简单的解决方案。您应该让GCC和Clang人员知道这一点,如果这不在他们的待办事项列表中。这是与OP要求的选项不同的文档。启用或禁用异常支持是通过
-fexce完成的选项
/
-无异常