Microsoft KB Archive/131148

From BetaArchive Wiki

BUG : Destructor Called Erroneously

Q131148

1.00 1.50 1.51 1.52 WINDOWS kbprg kbbuglist --------------------------------------------------------------------- The information to this article applies to : - The Microsoft C/C++ Compiler (CL.EXE) incuded with: Microsoft Visual C++ for Windows, versions 1.0, 1.5, 1.51, 1.52 --------------------------------------------------------------------- SYMPTOMS ======== The destructor may be called for an object not created. This is not a common problem. It happens under a specific circumstances and the sample code in the "More Information" section demonstrates this behavior. RESOLUTION ========== Two workarounds are suggested in the sample code (see NOTE #1 and NOTE #2). These workarounds may change the intended behavior of the code. STATUS ====== Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. We are researching this problem and will post new information here in the Microsoft Knowledge Base as it becomes available. MORE INFORMATION ================ Sample Code to Demonstrate Problem ---------------------------------- /* No special compile options needed. */ #include //AString int stringNumber = 0; void outputDebug(char *className, char *func, int number) { cout << "in " << className << "::" << className; cout << "() #" << number << " " << func << endl; } class AString{ public: AString(); AString(const AString &orig); virtual ~AString(); AString &operator=(const AString &orig); protected: int number; private: }; AString::AString() { number = ++stringNumber; outputDebug("AString", "copy1 constructor", number); } AString::AString(const AString &orig) { number = ++stringNumber; outputDebug("AString", "copy2 constructor", number); } AString::~AString() { outputDebug("AString", "Destructor", number); } AString &AString::operator=(const AString &orig) { outputDebug("AString", "operator=", number); return *this; } //ACompressor class ACompressor { public: ACompressor(AString& base); ~ACompressor(); }; inline ACompressor::ACompressor(AString& baseObject){ outputDebug("ACompressor", "Constructor", 33);} inline ACompressor::~ACompressor(){ outputDebug("ACompressor", "Destructor", 33);} //APath class APath : private AString{ public: APath() : AString(){} APath(char *) : AString(){} APath &operator =(const APath &path); //NOTE #1: if the line below is removed, the extraneous //call to AString::~AString() is not generated. inline operator AString() const { return *(AString *) this;} protected: private: APath(const APath &path); }; APath &APath::operator =(const APath &orig) { //NOTE #2:if the line below is removed OR the one in the NOTE #1 is //removed, the extraneous AString::~AString() call is not //generated. ACompressor pc(*this); //NOTE #3: The line below generates a call to //APath::operator AString(). AString::operator=(orig); //NOTE #4: Extra AString::~AString() destructor call made here //Assembly listing shows the extra destructor call. return *this; } int main() { char *filename = "c:\\someprog.exe"; APath exePath; exePath = filename; return 0; } Additional reference words: 1.00 1.50 1.51 1.52 8.00 8.00c KBCategory: kbprg kbbuglist KBSubcategory: CPPIss

Keywords : kb16bitonly kbCompiler kbCPPonly kbVC
Issue type :
Technology :


Last Reviewed: July 24, 1997
© 2001 Microsoft Corporation. All rights reserved. Terms of Use.