== Why is this an issue? When an exception is a pointer, it is difficult for the code that catches the exception to determine whether or not it needs to delete the pointed-to object. It is even more complicated than a traditional manual memory management scenario because the `throw` and the corresponding `catch` can be far apart. == How to fix it Throwing by value is more straightforward and less error-prone than using a pointer as an exception object. === Code examples ==== Noncompliant code example [source,cpp,diff-id=1,diff-type=noncompliant] ---- std::out_of_range globalException("Index too high"); void fn(int i) { // In this situation, the developer writing the "catch" has no way of knowing if the object pointed to by // the exception should be deleted or not if (i > 10) { throw (&globalException); // Noncompliant: the catch is supposed not to delete the pointer } else { throw (new std::out_of_range{"Invalid index"}); // Noncompliant: the catch is supposed to delete the pointer } } ---- ==== Compliant solution [source,cpp,diff-id=1,diff-type=compliant] ---- std::out_of_range globalException("Index too high"); void fn(int i) { if (i > 10) { throw (globalException); // Compliant: it throws a copy of the global variable } else { throw (std::out_of_range{"Invalid index"}); // Compliant: it throws a new object } } ---- == Resources === External coding guidelines * MISRA {cpp} 2008, 15-0-2 - An exception object should not have pointer type. === Related rules * S1044 - Exception classes should be caught by reference ifdef::env-github,rspecator-view[] ''' == Implementation Specification (visible only on this page) === Message Throw the exception by value. ''' == Comments And Links (visible only on this page) === on 14 Oct 2014, 17:51:53 Ann Campbell wrote: \[~samuel.mercier] please correct the following * Add a See section to the description listing the appropriate MISRA number * Fill in Applicability. * Make sure the appropriate MISRA C and MISRA {cpp} fields on the references tab are filled in === on 14 Oct 2014, 18:34:18 Ann Campbell wrote: Also [~samuel.mercier] I don't think Maintainability is appropriate here. The risks are * both caller and callee destroy the object - undefined behavior (likely runtime crash) * neither caller nor callee destroys the object - memory leak Since the worse outcome is a crash, I would associate this to Reliability === on 14 Oct 2014, 20:15:26 Freddy Mallet wrote: And if this is associated to the Reliability category, then the tag 'pitfall' should be replaced by 'bug' === on 17 Oct 2014, 09:12:45 Samuel Mercier wrote: \[~ann.campbell.2] caller cannot destroys the object, unless it also catches the exception it has thrown. But I agree about the memory leak, so I updated to Reliablity / Exception handling === on 20 Apr 2015, 10:00:42 Evgeny Mandrikov wrote: \[~ann.campbell.2] this rule has tag "bug" and severity "critical", but not enabled by default. Is it on purpose? === on 20 Apr 2015, 10:09:05 Ann Campbell wrote: It was on purpose [~evgeny.mandrikov], since this strikes me as potentially an issue of house style. If you think it is not, feel free to set it on by default. === on 11 May 2015, 20:24:44 Evgeny Mandrikov wrote: \[~ann.campbell.2] I don't see any valid reason for catching/throwing an exception by pointer, , while opposite is highly recommended, so don't see any reason to not activate this rule by default. endif::env-github,rspecator-view[]