1

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!

TTGroup
  • 3,575
  • 10
  • 47
  • 79
  • i don't know managed C++, though C++ doesnt need finally because it has RAII. See here for details: https://stackoverflow.com/a/161179/4117728 – 463035818_is_not_an_ai Nov 11 '21 at 10:52
  • 1
    @TTGroup - No sweat. Having on-topic tags will hopefully maximise your chances of getting a useful answer, and avoiding off-topic tags will hopefully avoid grabbing attention of people who can't give a useful answer. Unfortunately, I'm not familiar enough with Managed C++ to give a useful answer. But, in most (other) languages that support `finally`, the `finally` block is executed whether an exception is thrown and caught or not (e.g. cleanup that is needed both when an exception is thrown and handled and when no exception is thrown). – Peter Nov 11 '21 at 12:42
  • @HansPassant: I will consider and follow your suggestions. But if you pay attention, you will see something strange. Both Test2() and Test3() do not cause any exception, but Test2() function has a return statement in the try-block, which causes the difference in the value of the 'str' variable in the finally-block. I'm really confused at this point. – TTGroup Nov 12 '21 at 02:32

1 Answers1

0

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.

TTGroup
  • 3,575
  • 10
  • 47
  • 79