Listing 1: apr98.cpp Borlands temporary destructor bug
// This program demonstrates a couple of interesting // problems with Borland C++ 5.x. Subroutine Bar() // contains a static object Baz, which should be constructed // the first time the routine is called, and destroyed // when the program exits. This much works properly. // // The static object, Baz, is constructed using a pair // of temporary instances of Foo. The ISO standard dictates // that the lifetime of these temporaries should expire at // the end of the statement construucting Baz. However, // viewing the program output shows that the temporaries // are not destroyed until Bar() exits. The should also // be destroyed in the reverse of the order they were // constructed. // // Much worse, however, is the error that occurs the second // time that Bar() is called. Since the static object, Baz, // is not constructed the second time through the routine, // the two temporaries are not created. However, the routine // still attempts to destroy the non-existent routines upon // exit. This is very bad! Note that the bad char * value // in the non-existent temporaries may cause your version of // the program to crash. // // Build this program using the following command line: // // bcc32 apr98.cpp // #include <iostream.h> class Foo { public: Foo( int val, char *tag ) { m_val = val; m_tag = tag; cout << "constructing Foo(" << m_val << ", " << m_tag << ")\n"; } ~Foo() { cout << "destroying Foo(" << m_val << ", " << m_tag << ")\n"; } int m_val; char *m_tag; }; ostream &operator <<( ostream &os, const Foo &f ) { return os << f.m_val << ", " << f.m_tag; } int operator +( const Foo &lhs, const Foo &rhs ) { return lhs.m_val + rhs.m_val; } void Bar() { static Foo Baz = Foo( Foo( 1, "temp" ) + Foo( 2, "temp" ), "static" ); cout << "Baz = " << Baz << endl; } int main() { cout << "\nCalling Bar() for the first time...\n"; Bar(); cout << "\nCalling Bar() for the second time...\n"; Bar(); cout << "\nTerminating...\n"; return 0; } //End of File