Search code examples
c++invariantsnoexcept

Invariants and noexcept


In C++, if a method may throw only because the invariants of the class are not maintained, should I mark it noexcept?

For example, a list have a pointer to the link, which should be either nullptr or correct pointer, and a method dereferences this pointer. Does it prevent using noexcept?


Solution

  • If a function can exit via an exception, you should not mark it nothrow; nothrow is a guarantee that it never exits via an exception. It is essential that there be at least a few functions which never throw (and I mean never) if you want to write exception safe code.

    If the class invariants cannot be maintained, you shouldn't throw an exception; all you can reasonanbly do is abort the process. Don't confuse this with a constructor which cannot establish the invariants, however; its fine to throw then, since there will be no object afterwards which doesn't conform to the invariants. Also, in certain cases, it's valid to define a weaker set of invariants that hold after throwing. Say just enough to guarantee that the object can safely be destructed. This depends on the application (and how the design handles exceptions). But such functions cannot be declared nothrow.

    With regards to your concrete example: if the invariant is either a correct pointer or a null pointer, there's no way to test this and get an exception anyway. If the pointer is invalid (doesn't point to a valid object of the type, and isn't null), then you have undefined behavior. Anything can happen, and on real systems, anything does happen if you dereference the pointer.