Why does MFC define TRY
/CATCH
macros? Why can’t it use standard C++ exception handling?
This is another case of asking why they didn’t use the Space Shuttle to rescue Apollo 13.
MFC was first released in 1992. At that time, C++ was a cool new programming language that everybody was interested in. Back in the early days, there were no templates, there was no standard library, no placement new, no namespaces, and no exceptions.¹
That meant that the MFC team had to invent their own exceptions, which they did with macros like TRY
and CATCH
. These macros were deprecated in MFC 3.0 (released in 1994), but for compatibility the macros continue to exist so that pre-MFC-3.0 code remains source-level compatible. The macros now just do standard C++ try
and catch
operations, although there’s a _AFX_
OLD_
EXCEPTIONS
symbol you can define to make them revert to the old setjmp
-based fake exception handling, for binary compatibility.
MSDN has a guide to converting from MFC exceptions to C++ exceptions. So convert your code already. You’ve had 25 years.
¹ This implies that a failed new
didn’t throw a std::bad_alloc
exception, seeing as neither namespaces nor exceptions existed yet! Instead, a failed new
simply returned NULL
.²
² The nullptr
keyword wouldn’t exist for nearly 20 years.
MFC had to run on 16-bit Windows which did not have SEH in the first place.
“So convert your code already. You’ve had 25 years.” Well, the documentation says, “You probably do not need to convert existing code.” So that’s an excellent justification doing nothing.
As for new returning null, I had to support this for a while, but by that time placement new existed. So what I did was define a not_null_t with a static instance called not_null and created a placement-new version taking a not_null_t which enforced that failure would throw an exception. You would do:
my_struct* ps = new(not_null) my_struct;