gpt4 book ai didi

C++Builder 不会在 throw-catch-continue 上调用析构函数

转载 作者:搜寻专家 更新时间:2023-10-31 01:37:02 24 4
gpt4 key购买 nike

对于代码:

#include <stdio.h>

int ConstrCalls=0, DestrCalls=0;

struct Z
{
Z() { ConstrCalls++; }
~Z() { DestrCalls++; }
};

int main(int argc, char**)
{
bool Startup= true;

do
{
Z z;

try
{
if( Startup )
{
Startup= false;
throw( 1 );
}
else
{
break;
}
}
catch(int)
{
continue;
}
}
while(true);

printf( "ConstrCalls=%d DestrCalls=%d", ConstrCalls, DestrCalls);
return 0;
}
  • g++ 输出是 "ConstrCalls=2 DestrCalls=2",好的

  • Embarcadero C++Builder 2010、C++Builder 10 Seattle 输出为 "ConstrCalls=2 DestrCalls=1",即在 throw-catch 之后-continue 未调用析构函数!

C++Builder 能正常运行吗?

谢谢。

最佳答案

可悲的是......

the C++Builder 6, RAD Studio 2009 and XE7 Update 1, C++ compiler generates bad exception handling code (and in all likelihood all compilers in between--those are the compilers I current have access to). When an exception is thrown, the stack unwind code has been observed to:

  • Crash with an access violation
  • Fail to execute destructors when it should
  • Leak memory
  • Fire destructors twice

This makes it impossible to produce reliable, exception-safe, C++ software with this compiler.

看看C++ compiler exception handling is completely broken了解更多详情。

这来自“不应该触发析构函数”部分:

The following Button OnClick event handler constructs temporary Count objects only within the try/catch scope. Count objects keep track of the number of live instances in the count variable.

As an invariant the number of Count instances should be 0 following the try/catch. Instead this fails with BAD STACK UNWIND.

static int count = 0;

struct Count {
Count() { ++count; }
Count(const Count& rhs) { ++count; }
~Count( ) { --count; }
};

static int __fastcall destructorNotFired(int i=0, Count c=Count() ) {
throw Exception( "DESTRUCTOR NOT FIRED" );
}

void __fastcall TExceptionBugTestForm::ButtonDestructorNotFiredClick(TObject *Sender)
{
assert(count == 0);

try {
destructorNotFired( destructorNotFired() );
} catch ( Exception& e ) {
}

if (count != 0) {
ShowMessage( "BAD STACK UNWIND" );
}

assert(count == 0);
}

(与您的代码非常相似)。

异常处理在使用 clang++ 编译代码时效果很好(C++Builder 仅 64 位!= XE10)。

关于C++Builder 不会在 throw-catch-continue 上调用析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34826144/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com