2014-11-20 65 views
0

这里是一个我不认为应该发生一个很奇怪的事情:__最终在C++ Builder 2010中丢失范围?

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? 
    } 

如果我在try-catch块测试变量仍然被定义中删除return a;。在上面的构造之后,UnicodeString似乎超出了范围,是否有特定的原因?这是C++ Builder 2010的错误吗?我明白,从函数返回返回,但它应该仍然保留变量范围在__finally块不应该吗?

+2

这也发生在C++ Builder XE5 FWIW上。 – 2014-11-21 20:42:15

+3

昨天在Embarcadero论坛上讨论了这个相同的问题,在那里我提供了一个编译器正在做什么的分析:[为什么UnicodeString在这个例子中失去了范围?](https://forums.embarcadero.com/thread.jspa?线程ID = 110377)。 – 2014-11-21 23:48:38

+0

堆栈展开一直是bcc32中的越野车;例如[此错误](http://stackoverflow.com/a/27117266/1505939)已出现在驴的年份,并仍然存在 – 2014-11-27 02:51:59

回答

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将开始它的破坏。

+0

感谢您对此进行调查。看起来这是C++ Builder 2010中的一个错误,因为变量应该仍然保持在范围内,因为它也适用于矢量。我将使用解决方法。 – Coder12345 2014-11-21 18:42:43

+0

由'new'分配的内存永远不会在此代码中被删除,导致内存泄漏。我想'删除测试;'实际上应该在'__finally'块中。 – 2014-11-27 02:39:58

+0

另外,我不清楚C++ Builder是否保证'test'在这种情况下仍然保留相同的指针值(也许雷米会知道) – 2014-11-27 02:49:07

1

(雷米posted这意见,但没有张贴在这里的答案)

return语句是try...finally块内打,什么情况是,任何本地对象被销毁(因为它们将是其他任何return之前__finally块被输入。

因此,当您的代码达到test = "xyz";时,test已被破坏,导致未定义的行为。

我想这是一个语义问题,无论你称之为错误还是设计缺陷,但使用try...finally时都要记住这一点。我个人的建议是根本不使用它;标准C++技术try...catch和RAII可以解决任何问题。