MFC Exceptions.
Paul Martinsen -- pmartinsen@hort.cri.nz
Tuesday, December 17, 1996
Environment: VC++ 4.0, Win 95
Hello,
I was testing my error handling code last night & discovered what I
would call an error in the documentation. In many cases the MFC help
notes that a function could throw an exception, for example
CArray::InsertAt throws exceptions when there is insufficient memory
to insert the element. However, I discovered that it is actually a
POINTER that is thrown, not a CMemoryException (for example) object,
in otherwords the following code doesn't catch the error:
try
{ myArray.InsertAt(10,pNewObject);
} catch (CMemoryException)
{ AfxMessageBox(IDS_NO_MORE_MEMORY);
}
The catch line must read:
catch (CMemoryException *)
to catch the exception thrown by InsertAt. I looked at the code that
seems to be used for throwing these, eg AfxThrowMemoryException(),
and it seems to use a pointer to a static object which, of course,
doesn't need to be deleted. Does anybody know if this is always
true, ie do I every have to delete the pointer that I get in the
catch? Also, what is all this business with THROW and CATCH etc,
instead of the C++ throw & catch? Is this just MFC shouting so we
notice what is going on :), or should I be using them for my exception
handling too?
Paul.
John Addis -- jaddis@erols.com
Wednesday, December 18, 1996
[Mini-digest: 7 responses]
> From: Paul Martinsen
> To: mfc-l@netcom.com
> Subject: MFC Exceptions.
> Date: Monday, December 16, 1996 7:37 PM
>
> Environment: VC++ 4.0, Win 95
>
> Hello,
> I was testing my error handling code last night & discovered what I
> would call an error in the documentation. In many cases the MFC help
> notes that a function could throw an exception, for example
> CArray::InsertAt throws exceptions when there is insufficient memory
> to insert the element. However, I discovered that it is actually a
> POINTER that is thrown, not a CMemoryException (for example) object,
> in otherwords the following code doesn't catch the error:
All of the ::AfxThrowXxxxException() functions throw pointers rather than
actual objects.
> I looked at the code that
> seems to be used for throwing these, eg AfxThrowMemoryException(),
> and it seems to use a pointer to a static object which, of course,
> doesn't need to be deleted. Does anybody know if this is always
> true, ie do I every have to delete the pointer that I get in the
> catch?
For CException derived classes you should call the object's Delete()
method.
Ex:
catch(CMemoryException* pME)
{
...
pME->Delete();
}
> Also, what is all this business with THROW and CATCH etc,
> instead of the C++ throw & catch? Is this just MFC shouting so we
> notice what is going on :), or should I be using them for my exception
> handling too?
THROW and CATCH were maintained for backwards compatibility with previous
versions of MFC. If you are not concerned with this then you should be okay
using the normal c++ throw/catch keywords.
--
John Addis http://www.xorbit.com
"Power failure; please turn your computer on."
-----From: Mike Blaszczak
At 12:37 12/17/96 +1200, Paul Martinsen wrote:
>I looked at the code that seems to be used for throwing these,
>eg AfxThrowMemoryException(), and it seems to use a pointer to
>a static object which, of course, doesn't need to be deleted.
Obviously. If MFC needed throw a memory exception, where would it
get the memory to create it before throwing it?
>Does anybody know if this is always true, ie do I every have
>to delete the pointer that I get in the catch?
Yes. Please read the documentation. It explains that you must
call the Delete() member of CException-derived objects that you
catch. Like this:
try
{
m_array.InsertAt(11, "Kevin Dineen");
m_array.InsertAt(35, "Peter Siedorkiewicz");
m_array.InsertAt(5, "Ulf Samuelsson");
}
catch (CMemoryException* pEx)
{
pEx->ReportError();
pEx->Delete();
}
>Also, what is all this business with THROW and CATCH etc,
>instead of the C++ throw & catch? Is this just MFC shouting so we
>notice what is going on :), or should I be using them for my exception
>handling too?
Please read the documentation. It explains that the THROW and CATCH
macros are there just for backward compatibiltiy. MFC had exception
handling before the C++ Committee was even a twinkle in ANSI's eye.
In current versions of MFC (like MFC 4.0, which you're using), the
macros translate _almost_ directly to the C++ keywords. The
documentation explains how to convert the macros to C++ keywords,
if you'd like to do that. 'Course, you have to _read_ it, first.
.B ekiM
http://www.nwlink.com/~mikeblas/
I'm afraid I've become some sort of speed freak.
These words are my own. I do not speak on behalf of Microsoft.
-----From: Amir Shoval
Paul Martinsen wrote:
>
> Environment: VC++ 4.0, Win 95
>
> Hello,
> I was testing my error handling code last night & discovered what I
> would call an error in the documentation. In many cases the MFC help
> notes that a function could throw an exception, for example
> CArray::InsertAt throws exceptions when there is insufficient memory
> to insert the element. However, I discovered that it is actually a
> POINTER that is thrown, not a CMemoryException (for example) object,
> in otherwords the following code doesn't catch the error:
>
> try
> { myArray.InsertAt(10,pNewObject);
> } catch (CMemoryException)
> { AfxMessageBox(IDS_NO_MORE_MEMORY);
> }
>
> The catch line must read:
> catch (CMemoryException *)
Yes, This is *exactly* how it should read according to C++ language
rules (*not* MFC's). In fact, even a better one is:
catch (CMemoryException *e)
so you can use the exception pointer in the catch block to gain
information about the exception.
> to catch the exception thrown by InsertAt. I looked at the code that
> seems to be used for throwing these, eg AfxThrowMemoryException(),
> and it seems to use a pointer to a static object which, of course,
> doesn't need to be deleted. Does anybody know if this is always
> true, ie do I every have to delete the pointer that I get in the
> catch? Also, what is all this business with THROW and CATCH etc,
> instead of the C++ throw & catch? Is this just MFC shouting so we
> notice what is going on :), or should I be using them for my exception
> handling too?
>
> Paul.
MFC once did not support c++ try & catch mechanism and the exception
handling was done using MFC's macros TRY, CATCH & THROW. MFC docs says
you better use the new supported c++ mechanism for compatability
reasons. You can read about it in any c++ language reference.
Amir
--------------------------
Amir Shoval N.C.C. Israel
torin@netvision.net.il
--------------------------
-----From: SCS.007@mch.scn.de
>> Environment: VC++ 4.0, Win 95
>> to insert the element. However, I discovered that it is actually a
>> POINTER that is thrown, not a CMemoryException (for example) object,
>> in otherwords the following code doesn't catch the error:
>> try
>> { myArray.InsertAt(10,pNewObject);
>> } catch (CMemoryException)
>> { AfxMessageBox(IDS_NO_MORE_MEMORY);
>> }
>> The catch line must read:
>> catch (CMemoryException *)
>> to catch the exception thrown by InsertAt. I looked at the code that
Use TRY, CATCH, AND_CATCH, END_CATCH - It gives you an exception object.
>> catch? Also, what is all this business with THROW and CATCH etc,
>> instead of the C++ throw & catch? Is this just MFC shouting so we
>> notice what is going on :), or should I be using them for my exception
>> handling too?
During the days of VC++ 1.5, 1.52, the C++ team of Microsoft had not
supported exception handling machanism. Smart that the MFC team is, came up
with the TRY-CATCH mechanism - basically macros which provide that
functionality to you. MSVC 4.0 completely supports the C++ specification. You
should be thankful to them(MFC team). It does have some bugs though - for eg,
in VC++ 1.52, CFile doesnt throw exceptions in some cases, even thoough it is
documented. You can pardon them for such mistakes... .. sometimes.
Chandru.
Paul.
-----From: jmitchell@cc-mail.derwent.co.uk
--IMA.Boundary.447099058
Content-Type: text/plain; charset=ISO-8859-1
Ash Williams -- ash@digitalworkshop.co.uk
Friday, December 20, 1996
I'm suprised you haven't found anything in the help.
Yes you must delete the caught exception, but use the 'Delete' member
rather than the 'delete' operator.
Also TRY, THROW and CATCH are macros and were introduced before
try, throw and catch were a part of the language. Unfortunately they're
brain-dead as they rely on goto's, which of course means anything on
the stack doesn't get cleaned up. Actually they probably evaluate to
the language equivalent by now, but don't bother with them anyway just
in case.
Ash
| Вернуться в корень Архива
|