【问题标题】:__finally in C++ Builder 2010 losing scope?__finally 在 C++ Builder 2010 中失去作用域?
【发布时间】:2014-11-20 18:40:03
【问题描述】:

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

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 的错误吗?我知道 return 从函数返回,但它仍应在 __finally 块中保留变量范围,不是吗?

【问题讨论】:

  • 这也发生在 C++Builder XE5, FWIW 上。
  • 昨天在 Embarcadero 论坛上讨论了同样的问题,我提供了对编译器正在做什么的分析:Why is UnicodeString losing scope in this example?
  • 堆栈展开在 bcc32 中一直存在问题;例如this bug 已经存在多年了,现在仍然存在

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


【解决方案1】:

我做了更多的分析,发现一旦执行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 将启动它的销毁。

【讨论】:

  • 感谢您对此进行调查。这似乎是 C++ Builder 2010 中的一个错误,因为变量应该仍然保留在范围内,因为它也发生在向量中。我将使用解决方法。
  • new分配的内存在这段代码中从来不是deleted,导致内存泄漏。我猜delete test; 实际上应该在__finally 块内。
  • 我也不清楚 C++Builder 是否保证 test 在这种情况下仍然保留其相同的指针值(也许 Remy 会知道)
【解决方案2】:

(Remy posted这个在 cmets 但没有在这里发布答案)

return 语句在try...finally 块内被命中时,会发生任何本地对象被销毁(就像它们对任何其他return 一样)在@987654325 之前@块被输入。

所以当您的代码达到test = "xyz"; 时,test 已经被销毁,导致未定义的行为。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-02
    • 2020-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多