Click here to Skip to main content
Click here to Skip to main content

Standard Features Missing From VC++ 7.1. Part I: Exception Specifications

, 7 Apr 2004
Rate this:
Please Sign up or sign in to vote.
A look at exception specifications - a standard C++ feature not supported by VC++ 7.1.

Introduction

ISO/IEC Standard 14882 "Programming Languages - C++" was adopted in 1998. However, the first C++ compiler (EDG) that fully adheres to the Standard appeared in late 2002, and as of this writing, there is only one compiler on the market that claims full ISO Standard compliance (Comeau 4.3.3 front end).

Until several years ago, it seemed that Microsoft was not very interested in making their C++ compiler Standard conformant. Then, with Visual C++ 7.1 (comes with Visual Studio 2003), Microsoft released one of the most Standard compliant C++ compilers on the market. It is usually claimed to have 98% Standard adherence.

The goal of this article series is to take a look at the "other 2%" - the standard features not supported by Microsoft Visual C++ 7.1. I will cover the three major missing features:

  • exception specifications;
  • export keyword;
  • two-phase name lookup.

Other than that, there are some other minor deviations from the Standard (maximum number of template parameters, etc.).

The first part will cover exception specifications. This feature seems to be implemented on some popular compilers (sometimes I use GCC 3.2 which supports it), and even MSVC++ 7.1 parses exception specifications and somewhat takes them into account.

Some Theory Behind Exception Specifications

The C++ Standard [1] allows adding a list of exceptions that can be thrown, to a function signature:

void SomeFunction() throw (E1, E2); // may throw E1 or E2

means that SomeFunction can throw only exceptions of type E1 and E2, including the types publicly derived from E1 and E2.

An exception specification may be empty:

void SomeFunction() throw(); // no exceptions thrown

and this means that SomeFunction does not throw exceptions. Of course, a function can be declared without an exception specification:

void SomeFunction(); // can throw anything

which implies that SomeFunction can throw any exception.

An exception specification is not considered part of a function type, and the Standard explicitly forbids that a typedef contains one [1] [2]:

typedef void (*pf)() throw(E1);      // compile error

Exception specifications are not checked at compile time - they are enforced at run time. If a function declared with a function specification tries to throw an exception not listed in its exception specification, a call to std::unexpected() will be made instead. Essentially,

void SomeFunction() throw (E1, E2)
  {
  ...
  }  

is equivalent to:

void SomeFunction()
try
  {
  ...
  }
catch (E1)
  {
  throw;
  }
catch (E2)
  {
  throw;
  }
catch (...)
  {
  std::unexpected();
  }

The default behavior of std::unexpected() is to call std::terminate(), which by default calls abort()[2]. However, if std::bad_exception is listed in the exception specification, std::unexpected() will throw an implementation-defined object of this class instead.

For better control over unhandled exceptions, it is possible to set a user-defined version of unexpected(), by calling function std::set_unexpected():

void MyUnexpected();
...
set_unexpected(MyUnexpected);

In this case, MyUnexpected() must obey some pretty rigid rules set by the Standard [1]. It cannot return - instead it can either call std::terminate() or throw an exception. If this new exception is not listed in the exception specification, a std::bad_exception will be thrown instead. If std::bad_exception is not among allowed exceptions in the exception specification, std::terminate() will be called. The following flowchart describes this logic:

unexpected handler flowchart

Exception Specifications in Practice

Fundamentally, specifying exceptions as a part of a function signature looks like a good idea. A function declaration is a contract between the implementer and the users of the function, and making exceptions a part of this contract means that a user has more information how the function will interact with his code. However, things are not that simple, and most of C++ community now believe exception specifications should be avoided altogether [3][4][5].

The major issue with exception specifications seems to be the fact that checking exception specifications is mostly a run-time mechanism. One of the best features of C++ is its strong static type system. If the compiler tells me that I screwed something up, it means my customers will never find out about it, because I will need to fix it before shipping my software to them. In this case, if I put an empty exception specification as a part of my function declaration, and an exception is thrown, it will not be the compiler that tells me something is wrong; my application will die - hopefully during a test cycle, but maybe after it has been delivered to customers [8]. GCC 3.2 didn't even issue a warning when I threw an unspecified exception from a function. The reasons for not making exception specifications compile-time checked are good [4], but they don't make this run-time checking any more appealing.

Somewhat ironically, Java designers took a different approach [6]. Instead of run-time enforced exception specifications, they introduced compile-time checked exceptions. A Java method declaration must list all the checked exceptions that can be thrown from the method in the throws clause. There are also unchecked exceptions (derived either from RuntimeException or Error class) and they are not checked by Java compiler. When I was learning Java several years ago, checked exceptions looked like a great feature to me. However, people who actually use Java for real-world projects seem to have a different opinion [7]. They see checked exceptions as a major hurdle that brings down the productivity while adding nothing to code quality. Many Java programmers use all sorts of tricks to circumvent compile-time exceptions checking.

As for C#, Andres Hejlsberg and his team decided to leave any kind of exception checking out of their language, at least for the moment [9] [10].

Visual C++ 7.1 and Exception Specifications

Microsoft Visual C++ 7.1 ignores exception specifications unless they are empty [11]. Empty exception specifications are equivalent to __declspec(nothrow), and they can help the compiler to reduce code size.

If you are tempted to use this feature to optimize your code, be aware: the compiler will not do any checking for you. If it sees an empty exception specification, it will assume you know what you are doing and optimize away the mechanics for dealing with exceptions. If your function throws anyway - well, shame on you. Use this feature only if you are 100% positive your function does not throw and never will.

Setting a non-empty exception specification results in a compile warning: warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow). Using non-empty exception specifications for documentation purposes only is not a good idea - it will work fine with VC 7.1, but one day when we move to a compiler that implements exception specification in a Standard conformant way, we may run into troubles.

Conclusion

Exception specifications are a way to enrich function declarations with information about exceptions they may throw. While the core idea sounds good, in practice, it turned out to be a failure - not only in C++ where exception specifications are enforced at run-time, but also in Java where they are checked at compile-time.

References

  1. ISO/IEC 14882 Programming languages - C++, 1998
  2. Bjarne Stroustrup, "The C++ Programming Language", 3rd edition, Addison-Wesley, 1997
  3. Herb Sutter: A Pragmatic Look at Exception Specifications, CUJ 20(7) 2002.
  4. Jack Reeves: "The (B)Leading Edge" Guidelines for Using Exception Specifications, 1996 The C++ Report April 15, 1996
  5. Boost Library Requirements and Guidelines: Exception-specification rationale
  6. Java Language Specifications: Chapter 11: Exceptions
  7. Bruce Eckel: Does Java need Checked Exceptions?
  8. Murphy Laws
  9. Bill Venners with Bruce Eckel: The trouble with Checked Exceptions - A Conversation with Anders Hejlsberg, Part II
  10. Anson Horton: Why doesn't C# have exception specifications?, MSDN
  11. C++ Language Reference: Exception Specifications, MSDN.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Nemanja Trifunovic
Software Developer (Senior) SAP
United States United States
Born in Kragujevac, Serbia. Now lives in Boston area with his wife and daughters.
 
Wrote his first program at the age of 13 on a Sinclair Spectrum, became a professional software developer after he graduated.
 
Very passionate about programming and software development in general.

Comments and Discussions

 
Generalfunction typedefs and exception specification PinmemberFisico27-Dec-07 17:07 
GeneralRe: function typedefs and exception specification PinmemberNemanja Trifunovic28-Dec-07 4:06 
GeneralException Specification Part of Function's Type Pinmemberricecake5-Oct-06 10:09 
GeneralRe: Exception Specification Part of Function's Type PinmemberNemanja Trifunovic6-Oct-06 3:56 
GeneralIt's not missing, but hidden Pinmemberfert334528-Feb-06 6:04 
I don't know about 7.1, but 8.0 does have an implementation of exception specifications. If you use an undocumented switch /d1ESrt, you get it all - thrown types are checked, unexpected() is called etc. However I do agree that it's a rather questionable feature and I probably wouldn't use it myself even if it was enabled.
GeneralI couldn't disagree more. PinmemberProgramMax10-Dec-05 4:01 
GeneralRe: I couldn't disagree more. PinmemberNemanja Trifunovic10-Dec-05 4:34 
GeneralRe: I couldn't disagree more. PinmemberProgramMax10-Dec-05 13:26 
GeneralRe: I couldn't disagree more. PinmemberNemanja Trifunovic11-Dec-05 2:19 
GeneralRe: I couldn't disagree more. PinmemberProgramMax12-Dec-05 3:23 
GeneralRe: I couldn't disagree more. PinmemberNemanja Trifunovic13-Dec-05 1:49 
GeneralOn your conclusion PinmemberMartin Friedrich15-Apr-04 1:05 
GeneralGood introduction of C++ Exception Specifications but ... PinsussRobert F8-Apr-04 22:20 
GeneralRe: Good introduction of C++ Exception Specifications but ... Pinmemberdog_spawn9-Apr-04 1:42 
GeneralRe: Good introduction of C++ Exception Specifications but ... Pinmemberemilio_g9-Apr-04 2:01 
GeneralRe: Good introduction of C++ Exception Specifications but ... PinmemberMattyT13-Apr-04 22:25 
GeneralRe: Good introduction of C++ Exception Specifications but ... Pinmemberemilio_g13-Apr-04 22:53 
GeneralRe: Good introduction of C++ Exception Specifications but ... Pinmemberperlmunger14-Apr-04 4:51 
GeneralRe: Good introduction of C++ Exception Specifications but ... PinmemberMattyT14-Apr-04 16:48 
GeneralRe: Good introduction of C++ Exception Specifications but ... Pinmemberemilio_g14-Apr-04 19:43 
GeneralRe: Good introduction of C++ Exception Specifications but ... Pinmember.:fl0yd:.15-Apr-04 16:05 
GeneralRe: Good introduction of C++ Exception Specifications but ... Pinmemberemilio_g15-Apr-04 20:28 
GeneralRe: Good introduction of C++ Exception Specifications but ... PinmemberAlexandre B19-Apr-04 22:12 
GeneralRe: Good introduction of C++ Exception Specifications but ... PinmemberNemanja Trifunovic9-Apr-04 5:01 
GeneralNeed help... Pinmembermayankg1234522-Apr-04 18:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140709.1 | Last Updated 8 Apr 2004
Article Copyright 2004 by Nemanja Trifunovic
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid