{"id":5474,"date":"2018-07-12T19:51:12","date_gmt":"2018-07-12T19:51:12","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-to-error-handling\/"},"modified":"2023-06-26T11:48:04","modified_gmt":"2023-06-26T11:48:04","slug":"c-core-guidelines-rules-to-error-handling","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-to-error-handling\/","title":{"rendered":"C++ Core Guidelines: Rules for Error Handling"},"content":{"rendered":"<p>Error handling is an essential part of writing good software; therefore, the C++ core guidelines have about 20 rules for error handling.<\/p>\n<p><!--more--><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5472\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/07\/bobby-car.jpg\" alt=\"bobby car\" width=\"600\" height=\"400\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/07\/bobby-car.jpg 1280w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/07\/bobby-car-300x200.jpg 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/07\/bobby-car-1024x682.jpg 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/07\/bobby-car-768x512.jpg 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>&nbsp;First of all. Which aspects are involved in error handling according to the guidelines:<\/p>\n<ul>\n<li>Detecting an error<\/li>\n<li>Transmitting information about an error to some handler code<\/li>\n<li>Preserve the state of a program in a valid state<\/li>\n<li>Avoid resource leaks<\/li>\n<\/ul>\n<p>You should use exceptions for error handling. <a href=\"https:\/\/en.wikipedia.org\/wiki\/David_Abrahams_(computer_programmer)\">David Abrahams<\/a>, one of the founders of the Boost C++ Library and former member of the ISO C++ standardization committee, formalized in the document &#8220;<a href=\"https:\/\/www.boost.org\/community\/exception_safety.html\">Exception-Safety in Generic Components<\/a>&#8221; what exception-safety means. His <a href=\"https:\/\/en.wikipedia.org\/wiki\/Exception_safety\">Abrahams Guarantees<\/a> describe a fundamental contract if you think about exception-safety; therefore, I will mention them here in short and refer to them in the upcoming post. Here are the four levels of the contract from the already mentioned wiki page in decreasing order:<\/p>\n<ol>\n<li><b>No-throw guarantee<\/b>, also known as <b>failure transparency<\/b>: Operations are guaranteed to succeed and satisfy all requirements, even in exceptional situations. If an exception occurs, it will be handled internally and not observed by clients.<\/li>\n<li><b>Strong exception safety<\/b>, also known as <b>commit or rollback semantics<\/b>: Operations can fail, but failed operations are guaranteed to have no side effects, so all data retain their original values.<sup id=\"cite_ref-4\" class=\"reference\"><a href=\"https:\/\/en.wikipedia.org\/wiki\/Exception_safety#cite_note-4\"><br \/><\/a><\/sup><\/li>\n<li><b>Basic exception safety<\/b>, also known as a <b>no-leak guarantee<\/b>: Partial execution of failed operations can cause side effects. All invariants are preserved, and no resource leaks (including memory leaks) exist. Any stored data will contain valid values, even if they differ from before the exception.<\/li>\n<li><b>No exception safety<\/b>: No guarantees are made.<\/li>\n<\/ol>\n<p>Often, you can not fully recover from an error. Now, you have two options.<\/p>\n<p>First, let the program run in a simpler error state. This means the software is not fully functional anymore but provides at least reduced functionality. For example, it may not be possible for a defibrillator to apply the power but you can at least guide the operator.<\/p>\n<p>Or, second, restart the program. Often, this is the fastest and the easiest way to get into a safe state, recover, and get fully functional.&nbsp;<\/p>\n<p>The rules from the guidelines should help you to avoid the following kinds of errors:<\/p>\n<ul>\n<li>Type violations<code class=\"highlighter-rouge no-highlight\"><\/code><\/li>\n<li>Resource leaks<\/li>\n<li>Bounds errors<\/li>\n<li>Lifetime errors<code class=\"highlighter-rouge no-highlight\"><\/code><\/li>\n<li>Logical errors<\/li>\n<li>Interface errors<\/li>\n<\/ul>\n<p>After my more general remarks, let me start with the first three rules:<\/p>\n<ul>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Re-design\">E.1: Develop an error-handling strategy early in a design<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Re-throw\">E.2: Throw an exception to signal that a function can\u2019t perform its assigned task<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Re-errors\">E.3: Use exceptions for error handling only<\/a><\/li>\n<\/ul>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Re-design\">E.1: Develop an error-handling strategy early in a design<\/a><\/h3>\n<p>The entire rule consists only of this reason. &#8220;A consistent and complete strategy for handling errors and resource leaks is hard to retrofit into a system.&#8221; That is too little for an explanation. Error handling is a so-called cross-cutting concern such as logging or security. This means these concerns are challenging to address because they can not be easily modularized. They affect the entire software.<\/p>\n<p>Exception safety is an integral part of the interface design and has to be, therefore, addressed from the first beginning. Now the question is: What is an interface? My definition of an interface is quite broad.<\/p>\n<p><strong>An interface is a protocol between two components<\/strong>. One component may be a function, an object, a sub-system, or the entire system. This component may also be an external dependency, such as hardware or an operating system.<\/p>\n<p>You have two ways to communicate at the boundary level: regularly and irregularly. Regular communication is the functional aspect of the interface. Or, to say it differently: What the system should do. Irregular communication stands for the non-functional aspects. The non-functional aspect specifies how a system should perform. A big part of the non-functional aspects is exception-handling or what can go wrong. Often the non-functional aspects are just called quality attributes.<\/p>\n<p>From a general point of view, an interface consists of two components. Each component has to fulfill a special kind of contract.<\/p>\n<ol>\n<li>A <strong>Precondition<\/strong> that must always hold before a component is called.<\/li>\n<li>An <strong>Invariant<\/strong> must always be true during the execution of the component.<\/li>\n<li>A <strong>Postcondition<\/strong> that must always be true after the execution of the component.<\/li>\n<\/ol>\n<p>These terms go back <a href=\"https:\/\/en.wikipedia.org\/wiki\/Bertrand_Meyer\" title=\"\">Bertrand Meyer<\/a> and are known as <a href=\"https:\/\/en.wikipedia.org\/wiki\/Design_by_contract\">design by contract<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5473\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/07\/Design_by_contract.png\" alt=\"Design by contract\" width=\"350\" height=\"343\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/07\/Design_by_contract.png 490w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/07\/Design_by_contract-300x294.png 300w\" sizes=\"auto, (max-width: 350px) 100vw, 350px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: center;\">By <a href=\"https:\/\/it.wikipedia.org\/wiki\/Fabuio\" class=\"extiw\" title=\"it:Fabuio\">Fabuio<\/a> &#8211; <span class=\"int-own-work\" lang=\"en\">Own work<\/span>, <a href=\"http:\/\/creativecommons.org\/publicdomain\/zero\/1.0\/deed.en\" title=\"Creative Commons Zero, Public Domain Dedication\">CC0<\/a>, <a href=\"https:\/\/commons.wikimedia.org\/w\/index.php?curid=38020523\">Link<\/a><\/p>\n<p>Before I continue, I should mention that we may get <a href=\"https:\/\/herbsutter.com\/category\/c\/\">contracts<\/a> with C++20.<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Re-throw\">E.2: Throw an exception to signal that a function can\u2019t perform its assigned task<\/a><\/h3>\n<p>The consequence of this rule is that the caller of the function should handle the exception with a <span style=\"font-family: 'courier new', courier;\">try\/catch<\/span> statement. The critical question&nbsp;is: When should you throw an exception? Here are typical use cases:<\/p>\n<ul>\n<li>A precondition that cannot be met<\/li>\n<li>A constructor that cannot construct an object<\/li>\n<li>An out-of-range error<code class=\"highlighter-rouge no-highlight\"><br \/><\/code><\/li>\n<li>The inability to acquire a resource&nbsp;<\/li>\n<\/ul>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Re-errors\">E.3: Use exceptions for error handling only<\/a><\/h3>\n<p>This is, in my opinion, one of the worst misuses of exceptions. Exceptions are a kind of <span style=\"font-family: courier new, courier;\">goto<\/span> statement. Maybe your code guidelines forbid you to use <span style=\"font-family: courier new, courier;\">goto<\/span> statements. Therefore, you devised a clever idea: use exceptions for control flow. In the following example, the exception is used in the success case.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ don't: exception not used for error handling<\/span>\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">find_index<\/span>(vector<span style=\"color: #555555;\">&lt;<\/span>string<span style=\"color: #555555;\">&gt;&amp;<\/span> vec, <span style=\"color: #006699; font-weight: bold;\">const<\/span> string<span style=\"color: #555555;\">&amp;<\/span> x)\r\n{\r\n    try {\r\n        <span style=\"color: #006699; font-weight: bold;\">for<\/span> (gsl<span style=\"color: #555555;\">::<\/span>index i <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">0<\/span>; i <span style=\"color: #555555;\">&lt;<\/span> vec.size(); <span style=\"color: #555555;\">++<\/span>i)\r\n            <span style=\"color: #006699; font-weight: bold;\">if<\/span> (vec[i] <span style=\"color: #555555;\">==<\/span> x) <span style=\"color: #006699; font-weight: bold;\">throw<\/span> i;  <span style=\"color: #0099ff; font-style: italic;\">\/\/ found x<\/span>\r\n    } <span style=\"color: #006699; font-weight: bold;\">catch<\/span> (<span style=\"color: #007788; font-weight: bold;\">int<\/span> i) {\r\n        <span style=\"color: #006699; font-weight: bold;\">return<\/span> i;\r\n    }\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">1<\/span>;   <span style=\"color: #0099ff; font-style: italic;\">\/\/ not found<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The code snippet uses <span style=\"font-family: courier new, courier;\">gsl::index<\/span> from the <a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#S-gsl\">guideline support library<\/a>. In this case, the regular control flow is not separated from the exceptional control flow. In the success case, the code uses a <span style=\"font-family: 'courier new', courier;\">throw<\/span> statement; in the failure case, the code uses a <span style=\"font-family: 'courier new', courier;\">return<\/span> statement. If that is not confusing?<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>Of course, I will continue with the rules for error handling in the next post. In particular, I write about preconditions, postconditions, and invariants.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Error handling is an essential part of writing good software; therefore, the C++ core guidelines have about 20 rules for error handling.<\/p>\n","protected":false},"author":21,"featured_media":5472,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[478],"class_list":["post-5474","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-error-handling"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5474","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5474"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5474\/revisions"}],"predecessor-version":[{"id":6819,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5474\/revisions\/6819"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5472"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5474"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5474"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5474"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}