Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>"Throwing an exception" (sometimes also called "raising an exception") is a way to end a function when, for some reason, the function cannot complete the task it is expected to complete.</p> <p>Example: You have a function <code>f</code> that takes a <code>float</code> argument and is expected to compute and return its natural logarithm. Now at some point during the calculations it turns out that the argument that it was passed is <code>0</code>. There is no way to compute the logarithm of <code>0</code>, so what should the function do?</p> <p>One way to handle this situation is to return a special value (such as <code>NaN</code>, the not-a-number value of <code>float</code>), but this can be misleading to the caller of the function: The function was called on some variable, and returned some value. All looks normal, while in reality nothing is normal &ndash; the function could not do its job.</p> <p>Therefore, another way of handling this is to <em>throw an exception</em>. The effect is that the function ends, but does not return any value. Now, obviously, the calling function has a problem, because the normal flow of things has been disturbed: No value was returned from the function call. There are two possibilities for what can happen next: Either the calling function was prepared for this by having put the call of <code>f</code> in a try-catch clause:</p> <pre><code>try { log_of_val = f(val); } catch (const exception &amp;e) { /* Description of what to do when an exception is thrown by f. */ } </code></pre> <p>If the exception that is thrown by <code>f</code> matches the type of exception defined in one of the catch-clauses, then the first such catch-clause is executed.</p> <p>If there is no such catch-clause, the exception is thrown again, i.e. the calling function <em>also</em> ends abruptly and the caller of the caller is stopped to check whether there is some catch-code for the exception. If not, it also ends and that functions calling function is stopped, and so on, until the top of the call stack is reached (i.e. the level of <code>main</code>) and if there is still no catch-clause there, the entire program is terminated and the operating system is informed of the abortion of the process.</p> <p>So an exception has the power to bring down the entire process if there is no appropriate catch-clause. But an exception is <em>far</em> better than simply calling something like <code>exit(1)</code>, because it does not immediately terminate the process. It first gives the caller a chance to react to the problem, and then the caller's caller, and so on.</p> <p>The exception throwing mechanism also ensures that local variables are properly destructed and de-allocated before the current function ends. So, as far as automatic variables and dynamic memory that is managed by smart pointers and the like is concerned, you won't get memory leaks and similar problems.</p> <p>To sum up, exceptions (and the whole throwing and catching mechanism) is a way to deal with <em>unusual</em>, but <em>possible</em> and to some extent <em>expected</em> events in the flow of a program. Typically, it's events that can occur in a function call that render the proper execution of the function impossible, but that cannot be prevented from within the function. These events are often the responsibility of the calling function if it passes unsuitable arguments, or of the user who gives unsuitable input to the program. Also problems related to the state of the system, such as insufficient memory, tend to be handled by throwing exceptions.</p> <p>But unlike <em>bugs</em>, the programmer who wrote a function anticipated the possiblility of the problem and prepared the code with suitable throw and catch code to deal with it by having the program shut down in a controlled way, or otherwise react to the problem appropriately.</p> <p>Regarding the core of your question: <strong>What is the exception itself?</strong> The exception is an object created at the time when the "exception is thrown". You could view it as some kind of replacement for the return value, because the exception object is in fact passed to the caller, in a similar way as the return value would. But unlike with an actual return value, the caller is informed that what has happened is an exception and that it must handle this in the way I've described above. Further more, the <em>data type</em> of the exception is not the data type declared as return type of the function. In fact, it can be (almost) any data type. In particular, it can be a complex object with member variables that are initialized with values that describe the circumstances of the exception. A typical exception object is C++ is of class type, often (but not necessarily) defined as something like this:</p> <pre><code>#include &lt;exception&gt; class my_exception : public std::exception { public: explicit my_exception(const char *description) : std::exception() , description_(description) { } virtual const char *what() const noexcept { return description_; } private: const char *description_; }; </code></pre> <p>So it's a user-defined object that is constructed on a string, stores a pointer to the string internally, and provides a member function <code>what()</code> that returns the string. The idea is that the string is defined when the exception is thrown, and that it contains some description of the problem.</p> <p>The caller of <code>f</code> can then catch <em>this type</em> of exception by enclosing the call to <code>f</code> in a try-clause and adding a catch-clause for <code>my_exception</code>:</p> <pre><code>try { f(); } catch (const my_exception &amp;e) { std::cerr &lt;&lt; "A problem has occurred when evaluating f(): " &lt;&lt; e.what() &lt;&lt; std::endl; } </code></pre> <p>In this example, we use the exception object's <code>what()</code> function to print a description of the problem. After the catch-clause is completed, the caller will continue as normal. (If this is not desired, <code>throw;</code> can be used inside the catch-clause to re-throw the exception so it is passed to the caller's caller, and so on.)</p> <p>Note, again, that exception <em>can</em> be user-defined objects, and they <em>can</em> be derived from <code>std::exception</code>, and they <em>can</em> override the <code>what()</code> function to return a problem description as a string, but none of this is necessary. You can also throw the string itself, or an <code>int</code> as exception.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload