__最终在C ++ Builder 2010中失去了范围?

时间:2014-11-20 18:40:04

标签: scope c++builder try-catch-finally

这是一件非常奇怪的事情,我认为不应该发生:

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块中的变量范围不应该吗?

2 个答案:

答案 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 ++技术可以解决任何问题。