Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shall we use noexcept everywhere in this case?

I am working on a project which uses error codes, and exception handling is not allowed (we are using the nothrowing version of the new operator). Does it make sense to use the noexcept specifier on every function? Which are the possible pro and cons?

like image 447
nyarlathotep108 Avatar asked Feb 08 '23 16:02

nyarlathotep108


2 Answers

I think that it could be useful in your setup. The reason is that standard library containers and algorithms can use more optimised implementations of certain operations if these operations are noexcept().

like image 117
Angew is no longer proud of SO Avatar answered Feb 16 '23 02:02

Angew is no longer proud of SO


1.) I don't think it is worth it to do it on functions that are not special member functions. Special member functions are the only place that you will see a performance gain in the standard library from a noexcept declaration, afaik. (Possibly swap also?)

2.) You can use default declarations and noexcept at the same time, and you should rather than write out what would be defaulted! In a declaration like

my_class(const my_class&) noexcept = default;

This will cause the compiler to generate a default copy ctor and give it a noexcept declaration, even if the default copy ctor is forced to call a function that is not marked noexcept. In many cases, the compiler-generated special member functions are properly noexcept -- as long as they don't call something that is noexcept(false). So you may not even have to mark that many functions, in order to get the majority of the benefit, if you mark most of your low-level classes this way.

An example is, in C++11, std::string move ctor is not declared noexcept, even though it should be. It's not required by the standard until C++14. I believe that this was just an oversight -- I'm not aware of any implementation where std::string move ctor is actually throwing, nor can I imagine why it would.

But as a result, default move constructors of classes that contain std::string members do not acquire a noexcept specification, since they are forced to call a function that may throw. So, classes that contain std::string data members are often a great place to use my_class(my_class &&) noexcept = default in C++11, IMO.

3.) noexcept also has value because it helps to document the code. For instance, if you are making a library I would consider putting noexcept on API functions when applicable and you don't think you will make it throw later. But putting noexcept on functions which are just internal implementation details and not special member functions, isn't likely to add that much value, imo, although it can't hurt.

like image 29
Chris Beck Avatar answered Feb 16 '23 01:02

Chris Beck