【问题标题】:Are all functions "noexcept" if exceptions are disabled?如果异常被禁用,所有功能都是“noexcept”吗?
【发布时间】:2014-03-03 01:42:24
【问题描述】:

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

【问题讨论】:

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


【解决方案1】:

-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 会产生不同的输出。

【讨论】:

  • 我知道,行为完全不同。我的问题是:虽然我用-fno-exceptions(出于其他原因)编译了我的整个项目,但我仍然必须将移动构造函数声明为移动赋值运算符 noexcept 以启用 std::move_if_noexcept 的移动语义?
  • @TNA 好的,所以我误解了这一点。希望编辑更正它
  • @BЈовић 您能否为您的声明添加一个可靠的来源,即在编译器选项中添加 -fno-exceptions 不足以触发与手动标记所有函数 noexcept 相同的性能优化?现在你的支持论点有点模糊,似乎只解决了你对这个问题的早期(错误)理解。
  • 相关问题:-fno-exceptions 编译器选项会触发与在这种情况下标记函数 noexcept 相同的性能优势:youtube.com/watch?v=AG_63_edgUg 吗?
  • 更新:stackoverflow.com/questions/10787766/… 我测试了 GCC 和 clang 的行为,这似乎支持你的说法。
猜你喜欢
  • 2015-07-28
  • 1970-01-01
  • 2010-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-09
相关资源
最近更新 更多