这是一件非常奇怪的事情,我认为不应该发生:
UnicodeString test = "abc";
try
{
try
{
int a = 123;
return a; // This seems to produce a problem with "test" variable scope
}
catch (Exception &e)
{
// Some exception handler here
}
}
__finally
{
// At this point the "test" variable should still be in scope???
test = "xyz"; // PROBLEM here - test is NULL instead of "abc"! Why?
}
如果我删除return a;
块中的try-catch
,则仍会定义测试变量。有没有特别的原因为什么在上面的构造之后UnicodeString似乎超出了范围?这是C ++ Builder 2010的错误吗?我理解返回从函数返回但是它应该仍然保留__finally
块中的变量范围不应该吗?
答案 0 :(得分:3)
我进行了更多的分析,并且一旦执行return
语句,就会发现堆栈中的所有本地对象都被破坏了。如果您尝试使用堆对象,则不会发生这种情况。
UnicodeString *test = new UnicodeString("abc");
try
{
try
{
int a = 123;
return a; // This seems to produce a problem with "test" variable scope
}
catch (Exception &e)
{
// Some exception handler here
}
}
__finally
{
ShowMessage(*test); // "abc"
*test = "xyz";
}
delete test;
使用unique_ptr
之类的智能指针会再次导致__finally
中的对象丢失,因为return
会启动它的销毁。
答案 1 :(得分:1)
(Remy posted这个在评论中但没有在这里发表答案)
当在return
块中命中try...finally
语句时,会发生的事情是任何本地对象被销毁(因为它们将用于任何其他return
)之前< / strong>输入__finally
块。
因此,当您的代码到达test = "xyz";
时,test
已被销毁,从而导致未定义的行为。
我想这是一个语义问题,你是将这称为错误还是设计缺陷,但无论哪种方式,在使用try...finally
时都要记住这一点。我个人的建议是根本不使用它; try...catch
和RAII的标准C ++技术可以解决任何问题。