我使用的是Visual Studio 2019,我有一段代码使用finally块,我在每个Test1()
、Test2()
和Test3()
函数的开头声明了一个std::string对象。
我在每个函数的finally块中放置了一个断点,以查看str
变量,因此Test1()
和Test2()
函数中的str
变量被重置为Empty。仅在Test3()
中,功能不会重置。
我发现,如果在进入finally块之前遇到返回语句,str
将被重置。
我不明白发生了什么,在我的软件代码中,有很多地方使用了finally block,就像上面的例子一样,我需要了解它的确切机制,这样我才能修复应用程序中的潜在错误。
以下是测试功能的代码
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
}
}
非常感谢!
我调试并仔细检查,发现当遇到返回语句时,局部变量的析构函数会被破坏,析构函数在进入finally块之前被调用。只有在没有遇到返回语句的情况下,才会在Finally块之后调用这些析构函数(无论是否发生异常(。
由于这种不一致性,我只能通过不再在代码中使用任何finally块来解决它,用goto语句或等效语句替换它。
p/S:我正在配置带有SEH例外(/EHa(选项的项目。