Exceptions Don’t Solve the Problem (and create worse problems)
Brendan claims that the XPCOM nsresult return type is a significant cause of bloat due the need to rv-check every XPCOM method call, and proposes that XPCOM switch to use C++ exceptions. This is an idea that might appear attractive on the surface but would not only break the existing binary compatibility of XPCOM but would permanently destroy XPCOM as a component model with a standard binary API.
XPCOM is a component system that is based on binary compatibility of interfaces. While the layout of interface vtables is based on C++ vtable layout, it does not depend on the peculiarities of the C++ ABI including the layout of concrete classes or how RTTI is calculated or how exception handling is implemented.
Switching XPCOM component code to expect and use exceptions would immediately break not only any existing XPCOM binaries, and force a revision of the XPCOM ABI to version 2, but would also require a careful rewrite of the source code of these components. This would have the affect of breaking XPCOM’s current binary compatibility with MSCOM. Neither of these are automatic dealbreakers, thought they should be considered extremely carefully.
But exceptions have other side-affects which should be dealbreakers: the implementation of C++ exceptions is extremely dependent on the compiler implementation, both of exceptions themselves and of the underlying RTTI needed to handle them correctly. These implementation details differ between “minor” compiler versions such as MSVC6, 7, 7.1 and 8, as well as GCC 3.2, 3.4, and 4.0.
Finally, it is much harder to write and read good exception-based code than it is to write good nsresult-based code. This has shown up time and time again in Mozilla’s JS code: clean-looking and carefully-reviewed code lands which has unexpected error conditions: often the unexpected exception occurs from within a catch block.
Result codes (nsresult) encourage coders to make an explicit decision to ignore or handle failure conditions, and make the exit paths from a function body clear(er). Exceptions are hidden gotos: it is possible to write good exception-based code, but it is much harder to write (and perhaps more importantly, read).
Finally, it would take a significant amount of work to instrument the actual effects that exceptions might have on codesize and runtime excution. Simply enabling c++ exception handling and RTTI and disabling the NS_ENSURE_* macros is useless, because try/catch/finally blocks are required to properly handle flow control, and they typically have a significant cost in terms of stack-unwind code. I doubt that in the end exception-handling code would be significantly smaller or more efficient than result-handling code.
February 19th, 2006 at 9:53 pm
Comments at http://weblogs.mozillazine.org/roadmap/archives/2006/02/fresh_xpcom_thinking.html#comments.
/be
March 14th, 2006 at 11:19 am
Exceptional Measures…
Back in 2002 when we first started developing AllPeers (way before we switched from Win32 to Mozilla as a platform), we had a heated internal discussion about whether to use C++ exceptions or error codes in our APIs. I argued for former, on the princip…