我什么时候应该真正使用 noexcept?

2021-12-17 00:00:00 exception c++ c++11 noexcept

noexcept 关键字可以适当地应用于许多函数签名,但我不确定何时应该考虑在实践中使用它.根据我目前所读到的内容,最后一分钟添加的 noexcept 似乎解决了移动构造函数抛出时出现的一些重要问题.但是,对于一些实际问题,我仍然无法提供令人满意的答案,这些问题使我首先阅读了有关 noexcept 的更多信息.

The noexcept keyword can be appropriately applied to many function signatures, but I am unsure as to when I should consider using it in practice. Based on what I have read so far, the last-minute addition of noexcept seems to address some important issues that arise when move constructors throw. However, I am still unable to provide satisfactory answers to some practical questions that led me to read more about noexcept in the first place.

  1. 有很多我知道永远不会抛出的函数示例,但编译器无法自行确定.在所有这些情况下,我应该将 noexcept 附加到函数声明中吗?

  1. There are many examples of functions that I know will never throw, but for which the compiler cannot determine so on its own. Should I append noexcept to the function declaration in all such cases?

不得不考虑是否需要在 every 函数声明之后附加 noexcept 会大大降低程序员的工作效率(坦率地说,会很痛苦).在哪些情况下我应该更小心地使用 noexcept,哪些情况下我可以使用隐含的 noexcept(false)?

Having to think about whether or not I need to append noexcept after every function declaration would greatly reduce programmer productivity (and frankly, would be a pain in the neck). For which situations should I be more careful about the use of noexcept, and for which situations can I get away with the implied noexcept(false)?

在使用 noexcept 后,我什么时候才能真正看到性能改进?特别地,给出一个代码示例,在添加 noexcept 后,C++ 编译器能够为其生成更好的机器代码.

When can I realistically expect to observe a performance improvement after using noexcept? In particular, give an example of code for which a C++ compiler is able to generate better machine code after the addition of noexcept.

就我个人而言,我关心 noexcept 因为为编译器提供了更多的自由来安全地应用某些类型的优化.现代编译器会以这种方式利用 noexcept 吗?如果没有,我可以期待他们中的一些人在不久的将来这样做吗?

Personally, I care about noexcept because of the increased freedom provided to the compiler to safely apply certain kinds of optimizations. Do modern compilers take advantage of noexcept in this way? If not, can I expect some of them to do so in the near future?

推荐答案

我认为现在给出最佳实践"答案还为时过早,因为没有足够的时间在实践中使用它.如果在抛出说明符出现后立即问到这个问题,那么答案将与现在大不相同.

I think it is too early to give a "best practices" answer for this as there hasn't been enough time to use it in practice. If this was asked about throw specifiers right after they came out then the answers would be very different to now.

必须考虑是否需要在每个函数声明后附加 noexcept 会大大降低程序员的工作效率(坦率地说,这会很痛苦).

Having to think about whether or not I need to append noexcept after every function declaration would greatly reduce programmer productivity (and frankly, would be a pain).

好吧,那么在很明显函数永远不会抛出时使用它.

Well, then use it when it's obvious that the function will never throw.

在使用 noexcept 后,我什么时候才能真正看到性能改进?[...] 就我个人而言,我关心 noexcept 因为增加了编译器的自由度,可以安全地应用某些类型的优化.

When can I realistically expect to observe a performance improvement after using noexcept? [...] Personally, I care about noexcept because of the increased freedom provided to the compiler to safely apply certain kinds of optimizations.

似乎最大的优化收益来自用户优化,而不是编译器优化,因为可能会检查 noexcept 并对其进行重载.大多数编译器遵循无惩罚如果你不抛出异常处理方法,所以我怀疑它会在你的代码的机器代码级别上改变很多(或任何东西),尽管可能通过删除处理代码.

It seems like the biggest optimization gains are from user optimizations, not compiler ones due to the possibility of checking noexcept and overloading on it. Most compilers follow a no-penalty-if-you-don't-throw exception handling method, so I doubt it would change much (or anything) on the machine code level of your code, although perhaps reduce the binary size by removing the handling code.

在四大(构造函数、赋值函数,而不是析构函数,因为它们已经是 noexcept)中使用 noexcept 可能会像 noexcept 那样带来最好的改进code> 检查在模板代码中是常见的",例如在 std 容器中.例如,std::vector 不会使用你的类的移动,除非它被标记为 noexcept(否则编译器可以推断出它).

Using noexcept in the big four (constructors, assignment, not destructors as they're already noexcept) will likely cause the best improvements as noexcept checks are 'common' in template code such as in std containers. For instance, std::vector won't use your class's move unless it's marked noexcept (or the compiler can deduce it otherwise).

相关文章