Move operations should be noexcept (cpp:S5018)

Hi Community,
I have a question regarding the rule cpp:S5018: move operations should be noexcept.

We see it from time to time in our codebase whenever we compose our own data structure from std containers (mostly std::map, but also std::list is not noexcept movable).

So if I have in the simplest case:

struct A {
std::map<int, X> entries;
}

the rule would flag it. I can’t think of a proper solution though to make the move operation noexcept.

On the other hand, forbidding the move operation seems to be a drastic intervention as well. If the STL data structures don’t comply to this advice from the rule description: “If you can not implement your move operations so that they never throw, you may only provide copy operations that will be safer to use.”, why should I try to do so in my custom code? In these cases I stick with the rule-of-zero advice and set the sonar issue to won’t fix.

Curious though to hear how other users solve these situations.

I’m currently on sonarqube server v2025.1.1.

Hi @jsinge,

Thanks for your message. Another option to setting the issue to “won’t fix”, would be to implement the rule-of-five and make the special member functions noexcept = default. Some implementations of std::map are not noexcept movable due to allocating an end node. Marking the function as noexcept causes std::terminate to be called instead of throwing std::bad_alloc.

Doing this allows your class to be moved instead of copied when std::vector resizes its buffer.

Yes noexcept = default; would be a pragmatic alternative, still I don’t have a good feeling about it, due to the std::terminate implication.

The hint that this is relevant for resizing std::vector is helpful, thanks!

1 Like