This is a bit of a footgun and clang-tidy has a check for it: performance-noexcept-move-constructor. However, I don't think it's enabled by default!
This is a bit of a footgun and clang-tidy has a check for it: performance-noexcept-move-constructor. However, I don't think it's enabled by default!
On the other hand, writing special member functions at all(move & copy constructor/assignment, destructor) is a smell for types that don't just manage the lifetime of an object(unique_ptr like things). People should not generally be writing them and being open to the mistake of getting noexcept wrong.
I think you're missing a fair deal of insight into the issue.
The move semantics proposal documents this aspect in clear and unambiguous terms:
- Almost any class should be able to create a nothrow move assignment operator.
- a basic requirement is that a class must have a valid resource less state (i.e., remain in a valid state after having been moved)
- those that can't, shouldn't define move semantics.
That assertion completely misses the point. The scenarios involving move constructors throwing exceptions involve objects being stuck in an inconsistent/zombie state. In fact, the whole point of a move constructors is to avoid having to allocate memory.
Folks might be using mmap with MAP_POPULATE; they might have overcommit turned off; they might be operating in an rlimit/cgroup (like most container runtimes/orchestrators configure) that limits memory; they might be on a system which doesn't have virtual memory (plenty such systems exist in 64-bit architectures); they might be using calloc on an OS that zeros pessimistically/early; and so on.
Since you can also put noexcept(false) to indicate something throws exceptions and you didn't just forget to mark it noexcept, it's not a bad policy to say every move constructor should have a noexcept marker.
https://clang.llvm.org/extra/clang-tidy/checks/performance/n... constructor.html
Note that the way std::vector (and other STL containers) require noexcept move constructors for reallocation is by using template matching, and of course any other code might be doing this too, so having a compiler option that forced a constructor (or anything) to have a type signature different than the way it was declared would be a pretty dangerous thing to do since it'd be hard to know what the consequences would be.
match cxxConstructExpr(hasDeclaration(cxxConstructorDecl(isMoveConstructor(), unless(isNoThrow())).bind("throwing-move")))
You can put extra constraints on the caller if you'd like (e.g., isInStdNamespace()), though it's less trivial. Happy to help write something if you have a precise idea of what you want to match.