Exceptions: Converting from MFC Exception Macros
The new home for Visual Studio documentation is Visual Studio 2017 Documentation on docs.microsoft.com.
The latest version of this topic can be found at Exceptions: Converting from MFC Exception Macros.
This is an advanced topic.
This article explains how to convert existing code written with Microsoft Foundation Class macros — TRY, CATCH, THROW, and so on — to use the C++ exception-handling keywords try, catch, and throw
. Topics include:
Conversion advantages
Converting code with exception macros to use C++ exceptions
Advantages of Converting
You probably do not need to convert existing code, although you should be aware of differences between the macro implementations in MFC version 3.0 and the implementations in earlier versions. These differences and subsequent changes in code behavior are discussed in Exceptions: Changes to Exception Macros in Version 3.0.
The principal advantages of converting are:
Code that uses the C++ exception-handling keywords compiles to a slightly smaller .EXE or .DLL.
The C++ exception-handling keywords are more versatile: They can handle exceptions of any data type that can be copied (
int
, float,char
, and so on), whereas the macros handle exceptions only of classCException
and classes derived from it.
The major difference between the macros and the keywords is that code using the macros "automatically" deletes a caught exception when the exception goes out of scope. Code using the keywords does not, so you must explicitly delete a caught exception. For more information, see the article Exceptions: Catching and Deleting Exceptions.
Another difference is syntax. The syntax for macros and keywords differs in three respects:
Macro arguments and exception declarations:
A CATCH macro invocation has the following syntax:
CATCH( exception_class, exception_object_pointer_name )
Notice the comma between the class name and the object pointer name.
The exception declaration for the catch keyword uses this syntax:
catch( exception_type exception_name**)**
This exception declaration statement indicates the type of exception the catch block handles.
Delimitation of catch blocks:
With the macros, the CATCH macro (with its arguments) begins the first catch block; the
AND_CATCH
macro begins subsequent catch blocks, and theEND_CATCH
macro terminates the sequence of catch blocks.With the keywords, the catch keyword (with its exception declaration) begins each catch block. There is no counterpart to the
END_CATCH
macro; the catch block ends with its closing brace.The throw expression:
The macros use
THROW_LAST
to re-throw the current exception. Thethrow
keyword, with no argument, has the same effect.
Doing the Conversion
To convert code using macros to use the C++ exception-handling keywords
Locate all occurrences of the MFC macros TRY, CATCH,
AND_CATCH
,END_CATCH
, THROW, andTHROW_LAST
.Replace or delete all occurrences of the following macros:
TRY (Replace it with try)
CATCH (Replace it with catch)
AND_CATCH
(Replace it with catch)END_CATCH
(Delete it)THROW (Replace it with
throw
)THROW_LAST
(Replace it withthrow
)Modify the macro arguments so that they form valid exception declarations.
For example, change
CATCH(CException, e)
to
catch(CException* e)
Modify the code in the catch blocks so that it deletes exception objects as necessary. For more information, see the article Exceptions: Catching and Deleting Exceptions.
Here is an example of exception-handling code using MFC exception macros. Note that because the code in the following example uses the macros, the exception e
is deleted automatically:
TRY
{
// Do something to throw an exception.
AfxThrowUserException();
}
CATCH(CException, e)
{
if (m_bPassExceptionsUp)
THROW_LAST();
if (m_bReturnFromThisFunction)
return;
// Not necessary to delete the exception e.
}
END_CATCH
The code in the next example uses the C++ exception keywords, so the exception must be explicitly deleted:
try
{
// Do something to throw an exception.
AfxThrowUserException();
}
catch(CException* e)
{
if (m_bPassExceptionsUp)
throw;
if (m_bThrowDifferentException)
{
e->Delete();
throw new CMyOtherException;
}
if (m_bReturnFromThisFunction)
{
e->Delete();
return;
}
e->Delete();
}
For more information, see Exceptions: Using MFC Macros and C++ Exceptions.