Home > Blockchain >  C What is the behavior of a try-catch statement if an exception is thrown, and that exception does
C What is the behavior of a try-catch statement if an exception is thrown, and that exception does

Time:03-30

I'm interested to know more about how the following code logic behaves:

try
{
    // might, or might not do this: throw ExceptionTypeA;
    function_which_might_throw_exception_type_a();
    
    do_A(); // do we do A?
}
catch(ExceptionTypeB)
{
    // B will never be done
    do_not_do_B();
}

// C is always done (Edit: should always be done, but actually isn't)
do_C();

In short, this question can simply be stated as: Will the function do_A be called?*

*[If function_which_might_throw_exception_type_a() does throw ExceptionTypeA;... It is of course clear that do_A() will be called if function_which_might_throw_exception_type_a() does not throw an exception.]

The pseduocode above is supposed to express throwing an exception of a type which is different to the type of exception caught in the catch clause.

In other words, while there is a catch clause, the exception will not be caught here, because it is not of the correct type.

In such cases, does the compiler produce an output which skips the calling of do_A() entirely or does the compiler produce an output in which do_A() is called`?

I am fairly confident that if any exception is thrown in the try block, then the execution path is to leave the try block immediately. In other words, I think that do_A() is not called in the above pseudocode. (Assuming that the function function_which_might_throw_exception_type_a() does throw ExceptionTypeA.)

However I wanted to check this, because I was starting to have doubts.

FYI: I am looking at a block of code which would more sensibly be written as:

try
{
    // might, or might not do this: throw ExceptionTypeA;
    function_which_might_throw_exception_type_a();
    
    do_A(); // do we do A?

    // C **should** always be done
    do_C()
}
catch(ExceptionTypeB)
{
    // B will never be done
    do_not_do_B();
}
return something;

however, I think that this would not be equivalent to the first pseudocode.

Since C does not have a try-catch-finally type statement, the logic cannot be expressed in this way. (But I think it would be better if it could have been.)

CodePudding user response:

Will the function do_A be called?

In short – no. When an exception is thrown inside a try block, that block will be exited immediately. If the type of exception thrown is not handled by a corresponding catch block, then it will be treated much like an exception thrown outside a try block would be (possibly causing a stack unwind but, ultimately, program termination).

If you want your do_C() function to be called 'always', whatever type of exception is thrown, then you should add a catch(...) (known as a "catch-all clause") block after your other, specific catch block(s). This can be an empty statement/block; if so, the thrown exception is still caught (i.e. is not propagated further) but no specific action is taken.

A possible way to implement what you appear to want is as follows:

try
{
    // might, or might not do this: throw ExceptionTypeA;
    function_which_might_throw_exception_type_a();
    
    do_A(); // If the above throws, this WILL NOT be executed
}
catch(ExceptionTypeB)
{
    // B will never be done
    do_not_do_B();
}
catch(...) {} // This will catch "ExceptionTypeA" but do nothing about it ...
do_C();       // Will 'always' execute (unless an earlier catch re-throws)
return something;
  • Related