C++Builder 不会在 throw-catch-continue 上调用析构函数
C++Builder does not call destructor on throw-catch-continue
代码:
#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"
,ok
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)。
代码:
#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"
,okEmbarcadero 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 temporaryCount
objects only within thetry
/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)。