{"id":1085,"date":"2025-06-12T11:13:09","date_gmt":"2025-06-12T08:13:09","guid":{"rendered":"https:\/\/www.certbolt.com\/certification\/?p=1085"},"modified":"2026-01-01T14:00:17","modified_gmt":"2026-01-01T11:00:17","slug":"a-beginners-guide-to-exception-handling-using-try-catch","status":"publish","type":"post","link":"https:\/\/www.certbolt.com\/certification\/a-beginners-guide-to-exception-handling-using-try-catch\/","title":{"rendered":"A Beginner\u2019s Guide to Exception Handling Using Try-Catch"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">Exception handling is a powerful feature in C++ that provides a way to react to exceptional conditions (errors) that arise during the execution of a program. Unlike traditional error-handling techniques such as return codes, exception handling separates normal logic from error-handling logic, making programs easier to read and maintain.<\/span><\/p>\n<p><b>What is an Exception?<\/b><\/p>\n<p><span style=\"font-weight: 400;\">An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions. This can happen for various reasons, such as invalid input, hardware failure, or logical errors like division by zero. In C++, exceptions represent such anomalous conditions that programs need to handle gracefully.<\/span><\/p>\n<p><b>Advantages of Exception Handling Over Traditional Error Handling<\/b><\/p>\n<p><span style=\"font-weight: 400;\">C++ offers exception handling as an advantage over the C programming language, where errors are often managed by checking return codes. The traditional approach has several drawbacks:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">It mixes error-checking code with regular program logic, reducing clarity.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">It forces programmers to write repetitive conditional checks after each function call.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">It complicates maintenance and debugging because error paths are scattered.<\/span>&nbsp;<\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Exception handling solves these problems by providing a structured way to handle errors separately.<\/span><\/p>\n<p><b>Types of Exceptions in C++<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Exceptions can be broadly classified into two types based on when and how they occur:<\/span><\/p>\n<p><b>Synchronous Exceptions<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Synchronous exceptions occur as a direct result of the execution of specific instructions. Examples include accessing an invalid array index, dividing by zero, or dereferencing a null pointer. These exceptions happen predictably during program execution.<\/span><\/p>\n<p><b>Asynchronous Exceptions<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Asynchronous exceptions are events that occur independently of the current execution path. For example, hardware failures such as disk failures or external interrupts can cause asynchronous exceptions. These are less predictable and often harder to handle within software.<\/span><\/p>\n<p><b>The Core Keywords: try, catch, and throw<\/b><\/p>\n<p><span style=\"font-weight: 400;\">C++ provides three specialized keywords to support exception handling: <\/span><span style=\"font-weight: 400;\">try<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">catch<\/span><span style=\"font-weight: 400;\">, and <\/span><span style=\"font-weight: 400;\">throw<\/span><span style=\"font-weight: 400;\">. These keywords enable the definition and management of exception-handling code blocks.<\/span><\/p>\n<p><b>The try Block<\/b><\/p>\n<p><span style=\"font-weight: 400;\">The <\/span><span style=\"font-weight: 400;\">try<\/span><span style=\"font-weight: 400;\"> keyword is used to define a block of code where exceptions might occur. The code inside this block is said to be &#171;protected.&#187; If an exception is thrown within this block, control is transferred to the appropriate <\/span><span style=\"font-weight: 400;\">catch<\/span><span style=\"font-weight: 400;\"> block for handling.<\/span><\/p>\n<p><b>The throw Keyword<\/b><\/p>\n<p><span style=\"font-weight: 400;\">When an error condition occurs, the program can signal it by &#171;throwing&#187; an exception. The <\/span><span style=\"font-weight: 400;\">throw<\/span><span style=\"font-weight: 400;\"> keyword is used to raise an exception explicitly. This passes control to the nearest suitable <\/span><span style=\"font-weight: 400;\">catch<\/span><span style=\"font-weight: 400;\"> block designed to handle that particular type of exception.<\/span><\/p>\n<p><b>The catch Block<\/b><\/p>\n<p><span style=\"font-weight: 400;\">The <\/span><span style=\"font-weight: 400;\">catch<\/span><span style=\"font-weight: 400;\"> block follows the <\/span><span style=\"font-weight: 400;\">try<\/span><span style=\"font-weight: 400;\"> block and defines how to handle exceptions. Each <\/span><span style=\"font-weight: 400;\">catch<\/span><span style=\"font-weight: 400;\"> block specifies a parameter that indicates the type of exception it can handle. When an exception is thrown, the program searches for the matching <\/span><span style=\"font-weight: 400;\">catch<\/span><span style=\"font-weight: 400;\"> block to execute the appropriate error-handling code.<\/span><\/p>\n<p><b>Why is Exception Handling Important<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Exception handling plays a crucial role in developing robust and fault-tolerant software. It allows the program to deal with unexpected errors without crashing or producing incorrect results. Handling exceptions ensures:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The program can continue running or exit gracefully after encountering an error.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Separation of normal program logic from error handling improves code readability.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Developers can define custom error handling for different types of problems.<\/span>&nbsp;<\/li>\n<\/ul>\n<p><b>Basic Syntax of try-catch in C++<\/b><\/p>\n<p><span style=\"font-weight: 400;\">The fundamental structure of exception handling using try-catch looks like this:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">csharp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">try {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\/\/ Code that might throw an exception<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0throw exception; \/\/ Throw an exception if an error occurs<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">catch (ExceptionType e) {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\/\/ Code to handle the exception<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The <\/span><span style=\"font-weight: 400;\">try<\/span><span style=\"font-weight: 400;\"> block encloses the code where exceptions may arise. If an exception is thrown, the program looks for a <\/span><span style=\"font-weight: 400;\">catch<\/span><span style=\"font-weight: 400;\"> block with a matching exception type. If found, it executes the handler code.<\/span><\/p>\n<p><b>Using try-catch Blocks to Handle Exceptions in C++<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Exception handling in C++ is implemented primarily using the <\/span><span style=\"font-weight: 400;\">try<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">throw<\/span><span style=\"font-weight: 400;\">, and <\/span><span style=\"font-weight: 400;\">catch<\/span><span style=\"font-weight: 400;\"> keywords. Understanding how to properly use these keywords is essential for writing robust programs that can gracefully handle runtime errors.<\/span><\/p>\n<p><b>How Try-Catch Works in Practice<\/b><\/p>\n<p><span style=\"font-weight: 400;\">When you run C++ code, various errors can occur due to programmer mistakes, invalid user input, or unexpected situations like insufficient memory or hardware failures. By default, many errors cause the program to terminate abruptly, often displaying an error message. Exception handling provides a structured mechanism to intercept these errors and respond appropriately without crashing.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">A <\/span><span style=\"font-weight: 400;\">try<\/span><span style=\"font-weight: 400;\"> block contains code that might throw exceptions. If everything goes smoothly, the program continues after the try-catch block. However, if an exception is thrown inside the try block, control immediately transfers to the matching <\/span><span style=\"font-weight: 400;\">catch<\/span><span style=\"font-weight: 400;\"> block, where the exception is handled.<\/span><\/p>\n<p><b>Anatomy of a try-catch Block<\/b><\/p>\n<p><span style=\"font-weight: 400;\">A typical try-catch block looks like this:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">try {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\/\/ Code that may throw an exception<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0throw ExceptionType(); \/\/ Throws an exception object<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">catch (ExceptionType&amp; e) {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\/\/ Code to handle the exception<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The <\/span><span style=\"font-weight: 400;\">try<\/span><span style=\"font-weight: 400;\"> keyword marks the start of the block where exceptions may be thrown. The <\/span><span style=\"font-weight: 400;\">throw<\/span><span style=\"font-weight: 400;\"> statement raises an exception object or value. The <\/span><span style=\"font-weight: 400;\">catch<\/span><span style=\"font-weight: 400;\"> block catches the exception of the matching type and executes its handler code.<\/span><\/p>\n<p><b>Why Use try-catch Blocks?<\/b><\/p>\n<p><span style=\"font-weight: 400;\">The primary purpose of try-catch blocks is to separate normal code from error-handling code, which offers several advantages:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Readability<\/b><span style=\"font-weight: 400;\">: Error-handling logic does not clutter the main program flow.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Maintainability<\/b><span style=\"font-weight: 400;\">: Changes in error management do not affect the core logic.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Safety<\/b><span style=\"font-weight: 400;\">: Programs can recover or shut down gracefully in case of errors.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Modularity<\/b><span style=\"font-weight: 400;\">: Specific error handlers can be created for different exception types.<\/span>&nbsp;<\/li>\n<\/ul>\n<p><b>Examples of Exception Handling in C++<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Let\u2019s explore some practical examples to understand how try-catch works in C++.<\/span><\/p>\n<p><b>Example 1: Accessing Vector Elements Safely<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Vectors in C++ provide the <\/span><span style=\"font-weight: 400;\">at()<\/span><span style=\"font-weight: 400;\"> method to access elements safely. If an invalid index is accessed, it throws an <\/span><span style=\"font-weight: 400;\">out-of-range<\/span><span style=\"font-weight: 400;\"> exception.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;iostream&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;vector&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;exception&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">using namespace std;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">int main() {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0vector&lt;int&gt; vec = {0, 1};<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0try {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cout &lt;&lt; vec.at(2) &lt;&lt; endl; \/\/ This will throw an exception because index 2 is out of range<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0catch (const out_of_range&amp; e) {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cout &lt;&lt; &#171;Exception occurred: &#187; &lt;&lt; e.what() &lt;&lt; endl;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0return 0;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p><b>Explanation<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The <\/span><span style=\"font-weight: 400;\">vec. At (2),<\/span><span style=\"font-weight: 400;\"> call attempts to access the third element, which does not exist.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Since <\/span><span style=\"font-weight: 400;\">at()<\/span><span style=\"font-weight: 400;\"> throws an <\/span><span style=\"font-weight: 400;\">out_of_range<\/span><span style=\"font-weight: 400;\"> exception when the index is invalid, control passes to the catch block.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The catch block receives the exception object by reference and uses the <\/span><span style=\"font-weight: 400;\">what()<\/span><span style=\"font-weight: 400;\"> method to print the error message.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">This prevents the program from crashing and provides a graceful error message.<\/span>&nbsp;<\/li>\n<\/ul>\n<p><b>Example 2: Division by Zero Exception<\/b><\/p>\n<p><span style=\"font-weight: 400;\">We can create a function that throws an exception when a division by zero is attempted.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;iostream&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">using namespace std;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">double divide(int x, int y) {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0if (y == 0) {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0throw &#171;Division by zero error&#187;;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0return static_cast&lt;double&gt;(x) \/ y;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">int main() {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0int a = 15;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0int b = 0;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0try {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0double result = divide(a, b);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cout &lt;&lt; &#171;Result: &#187; &lt;&lt; result &lt;&lt; endl;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0catch (const char* msg) {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cerr &lt;&lt; &#171;Exception caught: &#187; &lt;&lt; msg &lt;&lt; endl;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0return 0;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p><b>Explanation<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The <\/span><span style=\"font-weight: 400;\">divide<\/span><span style=\"font-weight: 400;\"> function checks if the denominator is zero.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">If zero, it throws a string literal indicating the error.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The <\/span><span style=\"font-weight: 400;\">main<\/span><span style=\"font-weight: 400;\"> function wraps the call in a try block and catches the exception using <\/span><span style=\"font-weight: 400;\">catch(const char* msg)<\/span><span style=\"font-weight: 400;\">.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">This shows how you can throw and catch exceptions of different types (here, a C-style string).<\/span>&nbsp;<\/li>\n<\/ul>\n<p><b>Exception Handling with Multiple Catch Blocks<\/b><\/p>\n<p><span style=\"font-weight: 400;\">You can define multiple catch blocks to handle different exception types separately. This approach improves the granularity of error handling.<\/span><\/p>\n<p><b>Example<\/b><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;iostream&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;vector&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;exception&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">using namespace std;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">int main() {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0vector&lt;int&gt; vec = {1, 2};<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0try {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0int a = 10;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0int b = 0;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (b == 0) {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0throw runtime_error(&#171;Division by zero&#187;);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cout &lt;&lt; &#171;Division result: &#187; &lt;&lt; a \/ b &lt;&lt; endl;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cout &lt;&lt; vec.at(5) &lt;&lt; endl; \/\/ This will throw out_of_range exception<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0catch (const out_of_range&amp; e) {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cout &lt;&lt; &#171;Out of range exception: &#187; &lt;&lt; e.what() &lt;&lt; endl;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0catch (const runtime_error&amp; e) {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cout &lt;&lt; &#171;Runtime error: &#187; &lt;&lt; e.what() &lt;&lt; endl;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0catch (&#8230;) {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cout &lt;&lt; &#171;Unknown exception caught&#187; &lt;&lt; endl;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0return 0;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p><b>Explanation<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The first catch block handles <\/span><span style=\"font-weight: 400;\">out-of-range<\/span><span style=\"font-weight: 400;\"> exceptions from vector access.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The second catch block handles <\/span><span style=\"font-weight: 400;\">runtime_error<\/span><span style=\"font-weight: 400;\"> exceptions such as division by zero.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The third catch block, using ellipsis (<\/span><span style=\"font-weight: 400;\">&#8230;<\/span><span style=\"font-weight: 400;\">), catches any other exceptions that do not match previous handlers.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">This structure ensures that exceptions are handled according to their types, providing specific error messages.<\/span>&nbsp;<\/li>\n<\/ul>\n<p><b>Understanding Exception Propagation<\/b><\/p>\n<p><span style=\"font-weight: 400;\">If an exception is not caught within the function where it is thrown, it propagates up the call stack until it is caught or causes the program to terminate. This allows higher-level functions to handle errors thrown in lower-level functions.<\/span><\/p>\n<p><b>Example of Exception Propagation<\/b><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;iostream&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;exception&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">using namespace std;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">void funcB() {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0throw runtime_error(&#171;Error in funcB&#187;);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">void funcA() {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0funcB(); \/\/ No try-catch here, so the exception propagates up<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">int main() {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0try {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0funcA();<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0catch (const runtime_error&amp; e) {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cout &lt;&lt; &#171;Caught exception: &#187; &lt;&lt; e.what() &lt;&lt; endl;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0return 0;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p><b>Explanation<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">funcB<\/span><span style=\"font-weight: 400;\"> throws a <\/span><span style=\"font-weight: 400;\">runtime_error<\/span><span style=\"font-weight: 400;\"> exception.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">funcA<\/span><span style=\"font-weight: 400;\"> calls <\/span><span style=\"font-weight: 400;\">funcB<\/span><span style=\"font-weight: 400;\"> but does not catch the exception.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The exception propagates to the <\/span><span style=\"font-weight: 400;\">main<\/span><span style=\"font-weight: 400;\">, where it is caught in the try-catch block.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">This propagation mechanism lets you handle exceptions at appropriate levels in the call hierarchy.<\/span>&nbsp;<\/li>\n<\/ul>\n<p><b>Standard Exceptions in C++<\/b><\/p>\n<p><span style=\"font-weight: 400;\">The C++ Standard Library defines several exception classes in the <\/span><span style=\"font-weight: 400;\">&lt;exception&gt;<\/span><span style=\"font-weight: 400;\"> header to represent common error conditions. Using standard exceptions allows consistent error handling and better interoperability.<\/span><\/p>\n<p><b>Common Standard Exceptions<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">std::exception<\/span><span style=\"font-weight: 400;\"> &#8212; Base class for all standard exceptions.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">std::logic_error<\/span><span style=\"font-weight: 400;\"> &#8212; Indicates errors in program logic (e.g., domain errors).<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">std::runtime_error<\/span><span style=\"font-weight: 400;\"> &#8212; Represents errors that can only be detected during runtime.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">std::out_of_range<\/span><span style=\"font-weight: 400;\"> &#8212; Thrown when attempting to access elements outside valid ranges.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">std::invalid_argument<\/span><span style=\"font-weight: 400;\"> &#8212; Thrown when invalid arguments are passed to functions.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">std::bad_alloc<\/span><span style=\"font-weight: 400;\"> &#8212; Thrown when memory allocation fails.<\/span>&nbsp;<\/li>\n<\/ul>\n<p><b>Example Using Standard Exceptions<\/b><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;iostream&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;stdexcept&gt;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">using namespace std;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">int main() {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0try {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0throw invalid_argument(&#171;Invalid argument provided&#187;);<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0catch (const invalid_argument&amp; e) {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cout &lt;&lt; &#171;Caught invalid_argument exception: &#187; &lt;&lt; e.what() &lt;&lt; endl;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0catch (const exception&amp; e) {<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cout &lt;&lt; &#171;Caught general exception: &#187; &lt;&lt; e.what() &lt;&lt; endl;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0return 0;<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}<\/span><\/p>\n<p><b>Explanation<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The code throws an <\/span><span style=\"font-weight: 400;\">invalid_argument<\/span><span style=\"font-weight: 400;\"> exception.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The catch block for <\/span><span style=\"font-weight: 400;\">invalid_argument<\/span><span style=\"font-weight: 400;\"> executes first because it matches the exception type.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">If the first catch block were not present, the generic <\/span><span style=\"font-weight: 400;\">exception<\/span><span style=\"font-weight: 400;\"> catch block would handle it.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Using standard exceptions helps in writing clear, standardized exception handlers.<\/span>&nbsp;<\/li>\n<\/ul>\n<p><b>Best Practices for Exception Handling<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Proper exception handling is key to building maintainable and reliable software. Here are some widely accepted best practices:<\/span><\/p>\n<p><b>Use Exceptions for Exceptional Conditions<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Exceptions should represent unexpected or exceptional situations, not normal program flow. Avoid using exceptions for common conditional checks.<\/span><\/p>\n<p><b>Throw by Value, Catch by Reference<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Throw exceptions as objects, not pointers or primitive types. Catch exceptions by reference to avoid slicing and unnecessary copying.<\/span><\/p>\n<p><b>Provide Meaningful Exception Messages<\/b><\/p>\n<p><span style=\"font-weight: 400;\">When throwing exceptions, include descriptive messages or objects that help diagnose the problem.<\/span><\/p>\n<p><b>Avoid Catch-All Unless Necessary<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Use the catch-all (<\/span><span style=\"font-weight: 400;\">catch(&#8230;)<\/span><span style=\"font-weight: 400;\">) block sparingly, mainly for logging or cleanup before program termination. It should not be used for regular error handling.<\/span><\/p>\n<p><b>Clean Up Resources with RAII<\/b><\/p>\n<p><span style=\"font-weight: 400;\">To avoid resource leaks during exceptions, use Resource Acquisition Is Initialization (RAII) techniques. This means managing resources with objects that automatically release resources in their destructors.<\/span><\/p>\n<p><b>User-Defined Exceptions in C++<\/b><\/p>\n<p><span style=\"font-weight: 400;\">While C++ provides a rich set of standard exceptions, sometimes these are not enough to represent specific error conditions unique to your application. In such cases, defining custom exception classes is necessary.<\/span><\/p>\n<p><b>Why Create User-Defined Exceptions?<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">To represent domain-specific errors that standard exceptions don\u2019t capture.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">To carry additional information beyond just an error message.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">To improve error handling granularity and make debugging easier.<\/span>&nbsp;<\/li>\n<\/ul>\n<p><b>How to Define a User-Defined Exception Class<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Typically, user-defined exceptions inherit from <\/span><span style=\"font-weight: 400;\">std::exception<\/span><span style=\"font-weight: 400;\"> or one of its derived classes, so they integrate well with existing exception handling mechanisms.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Here is a simple example:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;exception&gt;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;string&gt;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">class MyException: public std::exception {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">private:\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0std::string message;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Public:\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0explicit MyException(const std::string&amp; msg) : message(msg) {}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0const char* what() const noexcept override {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return message.c_str();\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">};\u00a0\u00a0<\/span><\/p>\n<p><b>Explanation<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">MyException<\/span><span style=\"font-weight: 400;\"> inherits from <\/span><span style=\"font-weight: 400;\">std::exception<\/span><span style=\"font-weight: 400;\">.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">It stores a custom error message.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The <\/span><span style=\"font-weight: 400;\">what()<\/span><span style=\"font-weight: 400;\"> method is overridden to return the error message. This method is used by catch blocks to retrieve the exception description.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The <\/span><span style=\"font-weight: 400;\">noexcept<\/span><span style=\"font-weight: 400;\"> specifier indicates that <\/span><span style=\"font-weight: 400;\">what()<\/span><span style=\"font-weight: 400;\"> won\u2019t throw exceptions.<\/span>&nbsp;<\/li>\n<\/ul>\n<p><b>Throwing and Catching User-Defined Exceptions<\/b><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;iostream&gt;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">int main() {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0try {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0throw MyException(&#171;Something went wrong in my application&#187;);\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0catch (const MyException&amp; e) {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0std::cout &lt;&lt; &#171;Caught MyException: &#187; &lt;&lt; e.what() &lt;&lt; std::endl;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0return 0;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}\u00a0\u00a0<\/span><\/p>\n<p><b>Extending User-Defined Exceptions with Additional Data<\/b><\/p>\n<p><span style=\"font-weight: 400;\">You can add more data members to the exception class to provide richer context.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">class FileException: public std::exception {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">private:\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0std::string filename;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0std::string message;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">pPublic\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0FileException(const std::string&amp; file, const std::string&amp; msg) : filename(file), message(msg) {}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0const char* what() const noexcept override {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return message.c_str();\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0const std::string&amp; getFileName() const noexcept {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return filename;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">};\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">In the catch block, you can access both the message and the filename that caused the exception.<\/span><\/p>\n<p><b>Exception Specifications (Deprecated)<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Older C++ versions allowed you to specify which exceptions a function might throw using exception specifications. These are deprecated in C++11 and later, but understanding them is important for maintaining legacy code.<\/span><\/p>\n<p><b>Syntax of Exception Specifications<\/b><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">double myFunction() throw(int, std::bad_alloc);\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This means <\/span><span style=\"font-weight: 400;\">myFunction<\/span><span style=\"font-weight: 400;\"> may throw exceptions of type <\/span><span style=\"font-weight: 400;\">int<\/span><span style=\"font-weight: 400;\"> or <\/span><span style=\"font-weight: 400;\">std::bad_alloc<\/span><span style=\"font-weight: 400;\">. If it throws any other exception, <\/span><span style=\"font-weight: 400;\">std::unexpected()<\/span><span style=\"font-weight: 400;\"> is called.<\/span><\/p>\n<p><b>Dynamic Exception Specifications<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Allowed listing specific exceptions.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">If a function throws an exception not listed, <\/span><span style=\"font-weight: 400;\">std::unexpected()<\/span><span style=\"font-weight: 400;\"> is called.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">The empty throw specifier <\/span><span style=\"font-weight: 400;\">throw()<\/span><span style=\"font-weight: 400;\"> meant the function does not throw any exceptions.<\/span>&nbsp;<\/li>\n<\/ul>\n<p><b>Why Were They Deprecated?<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Poor usability: It was difficult to maintain accurate exception lists.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Unexpected behavior on violation: Calling <\/span><span style=\"font-weight: 400;\">std::unexpected()<\/span><span style=\"font-weight: 400;\"> usually results in program termination.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">C++11 introduced <\/span><span style=\"font-weight: 400;\">noexcept,<\/span><span style=\"font-weight: 400;\"> which expresses whether a function can throw or not in a simpler way.<\/span>&nbsp;<\/li>\n<\/ul>\n<p><b>Modern Alternative: noexcept<\/b><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">void foo() noexcept {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\/\/ This function promises not to throw exceptions\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Functions marked <\/span><span style=\"font-weight: 400;\">noexcept<\/span><span style=\"font-weight: 400;\"> will call <\/span><span style=\"font-weight: 400;\">std::terminate()<\/span><span style=\"font-weight: 400;\"> if an exception escapes, providing a safer and more predictable contract than dynamic exception specifications.<\/span><\/p>\n<p><b>Exception Safety Guarantees<\/b><\/p>\n<p><span style=\"font-weight: 400;\">When designing code that throws exceptions, understanding exception safety guarantees is crucial to prevent resource leaks, data corruption, or inconsistent program states.<\/span><\/p>\n<p><b>The Three Levels of Exception Safety<\/b><\/p>\n<p><b>Basic Guarantee<\/b><span style=\"font-weight: 400;\"> &#8212; The program remains in a valid state after an exception. No resource leaks occur. Data may be modified, but it remains consistent.<\/span><\/p>\n<p><b>Strong Guarantee<\/b><span style=\"font-weight: 400;\"> &#8212; Operations are either completed successfully or have no effect (transactional). If an exception is thrown, the program state is rolled back to before the operation.<\/span><\/p>\n<p><b>No-Throw Guarantee<\/b><span style=\"font-weight: 400;\"> &#8212; Operations guarantee not to throw exceptions. Common for destructors or swap operations.<\/span><\/p>\n<p><b>Example: Basic Guarantee<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Suppose you insert an element into a container, but an exception occurs during insertion. Basic guarantee ensures the container remains in a valid state, but the insertion may be partial.<\/span><\/p>\n<p><b>Example: Strong Guarantee<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Using copy-and-swap idiom or transactional operations, if the insertion fails, the container remains exactly as before the operation started.<\/span><\/p>\n<p><b>Stack Unwinding and RAII<\/b><\/p>\n<p><span style=\"font-weight: 400;\">When an exception is thrown, the\u00a0 C++ runtime performs <\/span><b>stack unwinding<\/b><span style=\"font-weight: 400;\">, which means destructors for all objects created since entering the try block are called in reverse order. This mechanism ensures proper cleanup of resources during exceptions.<\/span><\/p>\n<p><b>Resource Acquisition Is Initialization (RAII)<\/b><\/p>\n<p><span style=\"font-weight: 400;\">RAII is a C++ idiom that ties resource management to object lifetime: allocate resource in the constructor, release resource in the destructor. By using RAII, you ensure that resources like memory, file handles, and locks are automatically cleaned up when exceptions occur.<\/span><\/p>\n<p><b>Example: RAII Wrapper for a File Handle<\/b><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;cstdio&gt;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">class File {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0FILE* fp;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">public:\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0File(const char* filename) {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0fp = fopen(filename, &#171;r&#187;);\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (!fp) throw std::runtime_error(&#171;Failed to open file&#187;);\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0~File() {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (fp) fclose(fp);\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0File(const File&amp;) = delete;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0File&amp; operator=(const File&amp;) = delete;\u00a0\u00a0<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0FILE* get() const { return fp; }\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">};\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">If an exception occurs, the destructor closes the file automatically, preventing leaks.<\/span><\/p>\n<p><b>Throwing Exceptions in Constructors and Destructors<\/b><\/p>\n<p><b>Constructors<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Constructors can throw exceptions to indicate failure during object initialization.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">class Widget {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">public:\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0Widget() {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (\/* some error condition *\/) {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0throw std::runtime_error(&#171;Failed to construct Widget&#187;);\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">};\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">If a constructor throws, the object is considered not fully constructed, and destructors for fully constructed members are called automatically.<\/span><\/p>\n<p><b>Destructors<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Destructors should <\/span><b>never throw exceptions<\/b><span style=\"font-weight: 400;\"> because they are called during stack unwinding. Throwing exceptions inside destructors leads to <\/span><span style=\"font-weight: 400;\">std::terminate()<\/span><span style=\"font-weight: 400;\"> if another exception is already active. If a destructor must perform an operation that can fail, it should catch and handle exceptions internally, never letting them propagate.<\/span><\/p>\n<p><b>Exception Handling in Inheritance Hierarchies<\/b><\/p>\n<p><span style=\"font-weight: 400;\">When dealing with polymorphic types, exception handling should also consider inheritance.<\/span><\/p>\n<p><b>Catching Base vs Derived Exceptions<\/b><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">class BaseException: public std::exception { };\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">class DerivedException: public BaseException { };\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">try {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0throw DerivedException();\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">catch (BaseException&amp; e) {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\/\/ This will catch DerivedException as well because of polymorphism\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}\u00a0\u00a0<\/span><\/p>\n<p><b>Using Polymorphic Exception Handling<\/b><\/p>\n<p><span style=\"font-weight: 400;\">By catching base class references, you can handle multiple derived exceptions uniformly.<\/span><\/p>\n<p><b>Re-Throwing Exceptions<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Sometimes you catch an exception to perform some action (like logging), but want the exception to propagate further. You can re-throw the current exception using throw without arguments inside a catch block.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">try {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\/\/ code that throws\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">catch (const std::exception&amp; e) {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0std::cerr &lt;&lt; &#171;Caught exception: &#187; &lt;&lt; e.what() &lt;&lt; std::endl;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0throw; \/\/ Re-throw the same exception\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}\u00a0\u00a0<\/span><\/p>\n<p><b>Customizing Exception Behavior with std::unexpected and std::terminate<\/b><\/p>\n<p><span style=\"font-weight: 400;\">When a function violates its exception specification, C++ calls <\/span><span style=\"font-weight: 400;\">std::unexpected()<\/span><span style=\"font-weight: 400;\">. The default behavior of <\/span><span style=\"font-weight: 400;\">std::unexpected()<\/span><span style=\"font-weight: 400;\"> is to call <\/span><span style=\"font-weight: 400;\">std::terminate()<\/span><span style=\"font-weight: 400;\">, ending the program. You can customize these handlers:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;exception&gt;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;iostream&gt;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">void myUnexpected() {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0std::cerr &lt;&lt; &#171;Unexpected exception caught!&#187; &lt;&lt; std::endl;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0std::terminate();\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">int main() {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0std::set_unexpected(myUnexpected);\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\/\/ code with dynamic exception specification (deprecated)\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Since dynamic exception specifications are deprecated, using <\/span><span style=\"font-weight: 400;\">noexcept<\/span><span style=\"font-weight: 400;\"> and RAII patterns is preferred today.<\/span><\/p>\n<p><b>Exception Handling Performance Considerations<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Exception handling incurs some runtime cost, especially when exceptions are thrown and stack unwinding happens. However, modern compilers optimize try-catch mechanisms so that normal execution (when no exceptions occur) is efficient. Because exceptions should be reserved for exceptional conditions, their occasional overhead is justified by the benefits of cleaner error handling.<\/span><\/p>\n<p><b>Guidelines for Exception-Safe Code<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Prefer RAII to manage resources.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Write code with clear exception guarantees.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Avoid throwing exceptions from destructors.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Use <\/span><span style=\"font-weight: 400;\">noexcept<\/span><span style=\"font-weight: 400;\"> to mark functions that do not throw.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Catch exceptions by reference, not by value or pointer.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Avoid exception specifications except for <\/span><span style=\"font-weight: 400;\">noexcept<\/span><span style=\"font-weight: 400;\">.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Clean up all acquired resources before propagating exceptions.<\/span>&nbsp;<\/li>\n<\/ul>\n<p><b>Advanced Exception Handling Techniques in C++<\/b><\/p>\n<p><b>Exception Handling Best Practices in Large-Scale Applications<\/b><\/p>\n<p><span style=\"font-weight: 400;\">When working on large-scale software projects, robust exception handling is critical for stability and maintainability. Here are some best practices that experienced developers follow:<\/span><\/p>\n<p><b>Centralized Exception Handling<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Designate a central location, such as the main function or a dedicated error handler module, to catch and handle exceptions not caught elsewhere. This prevents uncaught exceptions from terminating the program unexpectedly. It also allows logging and graceful shutdown procedures.<\/span><\/p>\n<p><b>Use Exception Hierarchies<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Organize your exceptions into meaningful hierarchies to facilitate catching broad categories of errors or very specific issues. For example:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">class AppException: public std::exception {};\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">class DatabaseException: public AppException {};\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">class NetworkException public AppException {};\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This allows a catch block to handle all application exceptions or just specific ones as needed.<\/span><\/p>\n<p><b>Avoid Catch-All Unless Necessary<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Using <\/span><span style=\"font-weight: 400;\">catch(&#8230;)<\/span><span style=\"font-weight: 400;\"> should be a last resort. It can obscure the actual error and make debugging difficult. When you do use it, ensure you log sufficient information or re-throw the exception.<\/span><\/p>\n<p><b>Provide Meaningful Error Messages<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Exceptions should carry informative messages or error codes to aid diagnosis. Avoid generic messages like &#171;Error occurred.&#187; Instead, describe what failed and possibly why.<\/span><\/p>\n<p><b>Avoid Using Exceptions for Control Flow<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Exceptions should be reserved for exceptional conditions, not regular control flow. Using exceptions to handle normal logic can degrade performance and reduce code clarity.<\/span><\/p>\n<p><b>Exception Handling in Multithreaded Programs<\/b><\/p>\n<p><span style=\"font-weight: 400;\">With modern C++ supporting multithreading, handling exceptions in a multithreaded context requires careful design.<\/span><\/p>\n<p><b>Exception Propagation Across Threads<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Exceptions thrown in one thread do not propagate to other threads. Each thread must handle its exceptions independently. If an exception is not caught inside a thread, it calls <\/span><span style=\"font-weight: 400;\">std::terminate()<\/span><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><b>Strategies to Handle Exceptions in Threads<\/b><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Catch inside the thread function<\/b><span style=\"font-weight: 400;\">: Wrap the thread\u2019s work in a try-catch block and handle exceptions locally.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><b>Store exceptions for later re-throwing<\/b><span style=\"font-weight: 400;\">: Use <\/span><span style=\"font-weight: 400;\">std::exception_ptr<\/span><span style=\"font-weight: 400;\"> to capture exceptions and pass them back to the thread that spawned the worker. This can be combined with futures or promises.<\/span>&nbsp;<\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Example of capturing exceptions in threads:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;thread&gt;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;iostream&gt;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#include &lt;exception&gt;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">void threadFunction(std::exception_ptr&amp; eptr) {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0try {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0throw std::runtime_error(&#171;Error in thread&#187;);\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0catch (&#8230;) {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0eptr = std::current_exception();\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">int main() {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0std::exception_ptr eptr;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0std::thread t(threadFunction, std::ref(eptr));\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0t.join();\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0if (eptr) {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0try {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0std::rethrow_exception(eptr);\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0catch (const std::exception&amp; e) {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0std::cout &lt;&lt; &#171;Caught exception from thread: &#187; &lt;&lt; e.what() &lt;&lt; std::endl;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0return 0;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}\u00a0\u00a0<\/span><\/p>\n<p><b>Using std::future and std::promise for Exception Handling<\/b><\/p>\n<p><span style=\"font-weight: 400;\">, std::async<\/span><span style=\"font-weight: 400;\"> and futures automatically propagate exceptions thrown by the asynchronous function to the caller when calling. <\/span><span style=\"font-weight: 400;\">Get ()<\/span><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><b>Handling Exceptions in Constructors and Destructors Revisited<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Constructors and destructors have unique roles in exception handling and require special attention.<\/span><\/p>\n<p><b>Exceptions in Constructors<\/b><\/p>\n<p><span style=\"font-weight: 400;\">If a constructor throws an exception, the object\u2019s destructor is not called because the object is considered not fully constructed. However, destructors of any fully constructed base classes and members will be called.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">To manage resources safely during construction, use RAII wrappers for members that allocate resources. This ensures that partially constructed objects clean up properly.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Example:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">class Resource {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">public:\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0Resource() { \/* allocate resource *\/ }\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0~Resource() { \/* release resource *\/ }\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">};\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">class Widget {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0Resource res;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">public:\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0Widget() {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ If this throws, res&#8217;s destructor will be called automatically\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0throw std::runtime_error(&#171;Constructor failed&#187;);\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">};\u00a0\u00a0<\/span><\/p>\n<p><b>Exceptions in Destructors<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Destructors should never allow exceptions to propagate because:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Destructors are called during stack unwinding, so throwing exceptions leads to program termination.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">If a destructor must call code that can throw, it should catch exceptions internally and handle or log them without re-throwing.<\/span>&nbsp;<\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Example of a safe destructor:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">~MyClass() {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0try {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Cleanup code that might throw\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0catch (&#8230;) {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Log error and suppress exception\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}\u00a0\u00a0<\/span><\/p>\n<p><b>Exception Safety in Move and Copy Operations<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Move and copy constructors and assignment operators should also be exception-safe.<\/span><\/p>\n<p><b>Strong Guarantee in Assignment Operators<\/b><\/p>\n<p><span style=\"font-weight: 400;\">The copy-and-swap idiom is a common way to provide a strong exception guarantee in assignment operators:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">class MyClass {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">public:\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0MyClass&amp; operator=(MyClass other) {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0swap(*this, other);\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return *this;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0friend void swap(MyClass&amp; first, MyClass&amp; second) noexcept {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Swap internals\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">};\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This idiom ensures that if an exception occurs during copying, the original object remains unchanged.<\/span><\/p>\n<p><b>Move Constructors and noexcept<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Move constructors should be marked <\/span><span style=\"font-weight: 400;\">noexcept<\/span><span style=\"font-weight: 400;\"> whenever possible to enable optimizations such as in containers (e.g., <\/span><span style=\"font-weight: 400;\">std::vector<\/span><span style=\"font-weight: 400;\"> uses move if it is noexcept).<\/span><\/p>\n<p><b>Advanced Usage of throw, try, and catch<\/b><\/p>\n<p><b>Throwing Arbitrary Types<\/b><\/p>\n<p><span style=\"font-weight: 400;\">While it is best practice to throw exceptions derived from <\/span><span style=\"font-weight: 400;\">std::exception<\/span><span style=\"font-weight: 400;\">, C++ allows throwing any type, including built-in types. However, this is discouraged because it complicates error handling and type matching in catch blocks.<\/span><\/p>\n<p><b>Catching Multiple Exception Types<\/b><\/p>\n<p><span style=\"font-weight: 400;\">You can have multiple catch blocks to handle different exceptions separately:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">try {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\/\/ Code that may throw\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">catch (const std::invalid_argument&amp; e) {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\/\/ Handle invalid argument\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">catch (const std::out_of_range&amp; e) {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\/\/ Handle out-of-range\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">catch (&#8230;) {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\/\/ Catch all other exceptions\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}\u00a0\u00a0<\/span><\/p>\n<p><b>Nested try-catch Blocks<\/b><\/p>\n<p><span style=\"font-weight: 400;\">You can nest try-catch blocks to handle exceptions at different granularities:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">try {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0try {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Code that may throw\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0catch (const std::logic_error&amp; e) {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Handle logic errors\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0throw;\u00a0 \/\/ Re-throw for outer catch\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">catch (const std::exception&amp; e) {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\/\/ Handle all exceptions derived from std::exception\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}\u00a0\u00a0<\/span><\/p>\n<p><b>Exception Handling and Standard Library Integration<\/b><\/p>\n<p><b>std::exception and Derived Classes<\/b><\/p>\n<p><span style=\"font-weight: 400;\">C++ Standard Library defines many exception types derived from <\/span><span style=\"font-weight: 400;\">std::exception<\/span><span style=\"font-weight: 400;\">, including:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">std::logic_error<\/span><span style=\"font-weight: 400;\"> (e.g., <\/span><span style=\"font-weight: 400;\">std::invalid_argument<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">std::domain_error<\/span><span style=\"font-weight: 400;\">)<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">std::runtime_error<\/span><span style=\"font-weight: 400;\"> (e.g., <\/span><span style=\"font-weight: 400;\">std::range_error<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">std::overflow_error<\/span><span style=\"font-weight: 400;\">)<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">std::bad_alloc<\/span><span style=\"font-weight: 400;\"> (memory allocation failure)<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">std::out_of_range<\/span><span style=\"font-weight: 400;\"> (invalid container access)<\/span>&nbsp;<\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Using these classes improves compatibility and allows you to catch categories of errors easily.<\/span><\/p>\n<p><b>Exception Guarantees in STL Containers<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Most STL containers provide strong exception safety guarantees, meaning operations either complete successfully or leave the container unchanged. This is possible because they use <\/span><span style=\"font-weight: 400;\">noexcept<\/span><span style=\"font-weight: 400;\"> move constructors and strong exception-safe implementations internally.<\/span><\/p>\n<p><b>Debugging Exceptions in C++<\/b><\/p>\n<p><b>Using Exception Diagnostics<\/b><\/p>\n<p><span style=\"font-weight: 400;\">When debugging, knowing where an exception was thrown helps in diagnosis. Tools and techniques include:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Enabling core dumps or crash dumps.<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Using debuggers that break on throw statements (e.g., <\/span><span style=\"font-weight: 400;\">gdb<\/span><span style=\"font-weight: 400;\"> with <\/span><span style=\"font-weight: 400;\">catch throw<\/span><span style=\"font-weight: 400;\">).<\/span>&nbsp;<\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Adding detailed logging in catch blocks.<\/span>&nbsp;<\/li>\n<\/ul>\n<p><b>Handling Unknown Exceptions<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Using <\/span><span style=\"font-weight: 400;\">catch(&#8230;)<\/span><span style=\"font-weight: 400;\"> allows capturing any exception type, but you cannot inspect the exception object itself. This is useful as a last-resort safety net. Combine it with <\/span><span style=\"font-weight: 400;\">std::current_exception()<\/span><span style=\"font-weight: 400;\"> and <\/span><span style=\"font-weight: 400;\">std::rethrow_exception()<\/span><span style=\"font-weight: 400;\"> to attempt further handling.<\/span><\/p>\n<p><b>Writing Custom Exception Classes with Rich Context<\/b><\/p>\n<p><b>Adding Contextual Information<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Sometimes exceptions need more context than a message. You can add members such as error codes, source file names, line numbers, or additional metadata.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Example:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">class DetailedException: public std::exception {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0int errorCode;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0std::string file;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0int line;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0std::string message;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">public:\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0DetailedException(int code, const std::string&amp; file, int line, const std::string&amp; msg)\u00a0\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0: errorCode(code), file(file), line(line), message(msg) {}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0const char* what() const noexcept override {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return message.c_str();\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0int getCode() const noexcept { return errorCode; }\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0const std::string&amp; getFile() const noexcept { return file; }\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0int getLine() const noexcept { return line; }\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">};\u00a0\u00a0<\/span><\/p>\n<p><b>Macros to Automate File and Line Information<\/b><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">#define THROW_DETAILED_EXCEPTION(code, msg) \\\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0throw DetailedException(code, __FILE__, __LINE__, msg)\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">This macro simplifies throwing exceptions with the source location automatically.<\/span><\/p>\n<p><b>Exception Handling in Modern C++ Features<\/b><\/p>\n<p><b>Exceptions and Lambdas<\/b><\/p>\n<p><span style=\"font-weight: 400;\">You can throw exceptions inside lambda expressions and catch them outside:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">cpp<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CopyEdit<\/span><\/p>\n<p><span style=\"font-weight: 400;\">auto lambda = []() {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0throw std::runtime_error(&#171;Error in lambda&#187;);\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">};\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">try {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0lambda();\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">catch (const std::exception&amp; e) {\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00a0\u00a0\u00a0\u00a0std::cout &lt;&lt; e.what() &lt;&lt; std::endl;\u00a0\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">}\u00a0\u00a0<\/span><\/p>\n<p><b>Exceptions in Template Code<\/b><\/p>\n<p><span style=\"font-weight: 400;\">Templates that use operations that might throw must either propagate exceptions or catch and handle them internally. Exception handling in templates is similar to normal code but requires attention to type safety and exception specifications.<\/span><\/p>\n<p><b>When Not to Use Exceptions<\/b><\/p>\n<p><b>Embedded Systems and Performance-Critical Code<\/b><\/p>\n<p><span style=\"font-weight: 400;\">In systems with limited resources or hard real-time requirements, exceptions might be disabled or avoided due to overhead and unpredictability. In such cases, error codes or other mechanisms are preferred.<\/span><\/p>\n<p><b>Interfacing with C Code<\/b><\/p>\n<p><span style=\"font-weight: 400;\">When integrating C++ code with C libraries, error handling often uses return codes. Care must be taken to convert errors into exceptions safely if desired.<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Exception handling is a powerful feature in C++ that provides a way to react to exceptional conditions (errors) that arise during the execution of a program. Unlike traditional error-handling techniques such as return codes, exception handling separates normal logic from error-handling logic, making programs easier to read and maintain. What is an Exception? An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions. This can happen for various reasons, such as invalid input, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1049,1053],"tags":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.certbolt.com\/certification\/wp-json\/wp\/v2\/posts\/1085"}],"collection":[{"href":"https:\/\/www.certbolt.com\/certification\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.certbolt.com\/certification\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.certbolt.com\/certification\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.certbolt.com\/certification\/wp-json\/wp\/v2\/comments?post=1085"}],"version-history":[{"count":2,"href":"https:\/\/www.certbolt.com\/certification\/wp-json\/wp\/v2\/posts\/1085\/revisions"}],"predecessor-version":[{"id":9856,"href":"https:\/\/www.certbolt.com\/certification\/wp-json\/wp\/v2\/posts\/1085\/revisions\/9856"}],"wp:attachment":[{"href":"https:\/\/www.certbolt.com\/certification\/wp-json\/wp\/v2\/media?parent=1085"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.certbolt.com\/certification\/wp-json\/wp\/v2\/categories?post=1085"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.certbolt.com\/certification\/wp-json\/wp\/v2\/tags?post=1085"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}