如果禁用例外,所有功能都是“noexcept”吗?

时间:2014-02-06 08:13:14

标签: c++ gcc c++11 language-lawyer

如果通过使用-fno-exceptions进行编译来关闭异常,那么所有函数都被视为no例外std::move_if_noexcept,或者您是否仍需要声明函数noexcept?

1 个答案:

答案 0 :(得分:20)

-fno-exceptions将阻止您抛出异常,但它无法阻止从库中抛出异常。

例如,下一个示例将因未捕获的异常而终止:

#include <vector>

int main()
{
    std::vector<int> v{1,2,3,4,5,6};

    return v.at(55);
}

但由于-fno-exceptions选项:

,下一个示例将无法编译
int main()
{
    throw 22;
}

失败了:

g++   -std=c++11 -g  -Wall -Wextra -fno-exceptions ./garbage.cpp 
./garbage.cpp: In function ‘int main()’:
./garbage.cpp:4:8: error: exception handling disabled, use -fexceptions to enable
  throw 22;

来自this article, Doing without chapter

  

使用C ++关键字(如throw,try和catch)的用户代码   即使用户代码包含libstdc ++标头,也会产生错误   并使用像basic_iostream这样的结构。


另一方面,noexcept将该方法标记为不抛出异常的方法。任何抛出的异常都会调用std::terminate(参见c ++标准中的[except.terminate] / 2)。

下一个例子:

struct A
{
    void foo() noexcept
    {
        throw 33;
    }
};

int main()
{
    A a;
    try
    {
        a.foo();
    }
    catch(...)
    {
    }
}

终止于:

terminate called after throwing an instance of 'int'
Aborted (core dumped)

总结:当您使用-fno-exceptions并将函数标记为noexcept时,行为会有很大不同。


  

虽然我用-fno-exceptions编译我的整个项目(由于其他原因)我仍然需要声明移动构造函数一个移动赋值运算符noexcept为std :: move_if_noexcept启用移动语义吗?

使用该选项时,这些功能不会自动标记为noexcept。你必须手动完成。不允许编译器进行此类修改。

如果允许这样的修改,那么this example会产生不同的输出。