Discuss how the finally block works

92 Views Asked by At

I am using Visual Studio 2019, and I have a piece of code that uses finally block, I have declared a std::string object at the beginning of each Test1(), Test2() and Test3() functions.

I put a break point inside the finally block of each function to see the str variable, and as a result the str variable is reset to Empty in the Test1() and Test2() functions. Only in Test3() function is not reset.

I discovered that str is reset if a return statement is encountered before entering the finally block.

I don't understand what is going on, in the code of my software there are many places where finally block is used like the example above, I need to understand the exact mechanism of it so that I can fix potential bugs in the application.

The following is the code of the Test functions

void Test1()
{
    string str = "Test1";
    try
    {
        int* i = NULL;
        *i = 0;         //This command will raise an exception
        return;
    }
    catch (Exception^ e)
    {
        return;
    }
    finally
    {
        int i = 0; //'str' is rested as empty when entering here
    }
}

void Test2()
{
    string str = "Test2";
    try
    {
        int* i = NULL;
        return;
    }
    catch (Exception^ e)
    {
        return;
    }
    finally
    {
        int i = 0;  //'str' is rested as empty when entering here
    }
}

void Test3()
{
    string str = "Test3";
    try
    {
        int* i = NULL;
    }
    catch (Exception^ e)
    {

    }
    finally
    {
        int i = 0; //'str' is NOT reset to empty when entering here
    }
}

Thank you so much!

1

There are 1 best solutions below

0
TTGroup On

I debug and double check, found that destructor of local variables will be destroyed when encountering return statement, destructor is called before entering finally block. Only if no return statement is encountered will these destructors be called after the Finally block (regardless of whether an exception occurs or not).

Due to this inconsistency, I could only work around it by not using any finally blocks in the code anymore, replacing it with goto statements or equivalent.

P/S: I am configuring the project with SEH Exceptions (/EHa) option.