PRB: Exception Not Caught Using CArchive or CFile (157073)
The information in this article applies to:
- The Microsoft Foundation Classes (MFC), when used with:
- Microsoft Visual C++, 32-bit Editions 2.0
- Microsoft Visual C++, 32-bit Editions 2.1
- Microsoft Visual C++, 32-bit Editions 2.2
- Microsoft Visual C++, 32-bit Editions 4.0
- Microsoft Visual C++, 32-bit Editions 4.1
- Microsoft Visual C++, 32-bit Enterprise Edition 4.2
- Microsoft Visual C++, 32-bit Professional Edition 4.2
This article was previously published under Q157073 SYMPTOMS
When using CArchive or CFile, Visual C++ exceptions may not be caught if
the CArchive and/or CFile are in the same try block as a read or write:
void Test1()
{
try {
//Drive A: should contain a floppy with zero bytes free
CFile file("A:\\BadFile.tmp", CFile::modeCreate
| CFile::shareExclusive | CFile::modeWrite );
try {
CArchive archive(&file, CArchive::store);
//Fill up disk, and cause a
//CFileException::diskFull exception
while(1)
archive << (DWORD)17;
}
catch ( CFileException* ex ) {
ex->Delete();
}
catch (...) {
ASSERT(FALSE);
}
}
catch ( CFileException* ex ) {
ex->Delete();
}
catch (...){
ASSERT(FALSE);
}
}
In this case, if the disk is full, the exception is not caught, terminate()
is called, and the application exits.
CAUSE
In the process of handling exceptions, objects inside the try block are
destructed before the first catch block. During unwinding, when a second
exception is thrown by a destructor before the first exception is caught,
terminate() is called.
Both the destructors for CArchive and CFile attempt to flush the buffer and
close the open file. This can cause a second exception to get thrown and
terminate() to get called.
RESOLUTION
Make sure that the CArchive or CFile object is not inside the same try
block as any read or write on that object.
The CArchive object should also not be inside of the same try block as the
CFile object it uses unless the CArchive was created in the
CArchive::bNoFlushOnDelete mode. If this mode is used, the CArchive and
CFile can safely be in the same try block. Care must be taken to call
CArchive::Flush() before the CArchive is deleted, and in a separate try
block. The second example below shows using a CArchive in this mode.
STATUS
This behavior is by design.
Modification Type: | Major | Last Reviewed: | 12/2/2003 |
---|
Keywords: | kbExceptHandling kbFileIO kbprb KB157073 |
---|
|