Wednesday, April 07, 2010

System error support in C++0x - part 1

Among the many new library features in C++0x is a little header called <system_error>. It provides a selection of utilities for managing, well, system errors. The principal components defined in the header are:

  • class error_category
  • class error_code
  • class error_condition
  • class system_error
  • enum class errc

I had a hand in the design of this facility, so in this series of posts I will try to capture the rationale, history, and intended uses of the various components.

Where to get it

A complete implementation, and one that supports C++03, is included in Boost. I'd guess that, at this point in time, it is probably the best tested implementation in terms of portability. Of course, you have to spell things starting with boost::system:: rather than std::.

An implementation is included with GCC 4.4 and later. However, you must compile your program with the -std=c++0x option in order to use it.

Finally, Microsoft Visual Studio 2010 will ship with an implementation of the classes. The main limitation is that the system_category() does not represent Win32 errors as was intended. More on what that means later.

(Note that these are just the implementations that I am aware of. There may be others.)


Here are the types and classes defined by <system_error>, in a nutshell:

  • class error_category - intended as a base class, an error_category is used to define sources of errors or categories of error codes and conditions.
  • class error_code - represents a specific error value returned by an operation (such as a system call).
  • class error_condition - something that you want to test for and, potentially, react to in your code.
  • class system_error - an exception used to wrap error_codes when an error is to be reported via throw/catch.
  • enum class errc - a set of generic error condition values, derived from POSIX.
  • is_error_code_enum<>, is_error_condition_enum<>, make_error_code, make_error_condition - a mechanism for converting enum class error values into error_codes or error_conditions.
  • generic_category() - returns a category object used to classify the errc-based error codes and conditions.
  • system_category() - returns a category object used for error codes that originate from the operating system.


This section lists some of the guiding principles I had in mind in designing the facility. (I cannot speak for the others involved.) As with most software projects, some were goals at the outset and some were picked up along the way.

Not all errors are exceptional

Simply put, exceptions are not always the right way to handle errors. (In some circles this is a controversial statement, although I really don't understand why.)

In network programming, for example, there are commonly encountered errors such as:

  • You were unable to connect to a remote IP address.
  • Your connection dropped out.
  • You tried to open an IPv6 socket but no IPv6 network interfaces are available.

Sure, these might be exceptional conditions, but equally they may be handled as part of normal control flow. If you reasonably expect it to happen, it's not exceptional. Respectively:

  • The IP address is one of a list of addresses corresponding to a host name. You want to try connecting to the next address in the list.
  • The network is unreliable. You want to try to reestablish the connection and only give up after N failures.
  • Your program can drop back to using an IPv4 socket.

Another requirement, in the case of Asio, was a way to pass the result of an asynchronous operation to its completion handler. In this case, I want the operation's error code to be an argument to the handler callback. (An alternative approach is to provide a means to rethrow an exception inside the handler, such as .NET's BeginXYZ/EndXYZ asynchronous pattern. In my opinion, that design adds complexity and makes the API more error-prone.)

Last, but not least, some domains will be unable or unwilling to use exceptions due to code size and performance constraints.

In short: be pragmatic, not dogmatic. Use whatever error mechanism suits best in terms of clarity, correctness, constraints, and, yes, even personal taste. Often the right place to make the decision between exception and error code is at the point of use. That means a system error facility should support both.

Errors come from multiple sources

The C++03 standard recognises errno as a source of error codes. This is used by the stdio functions, some math functions, and so forth.

On POSIX platforms, many system operations do use errno to propagate errors. POSIX defines additional errno error codes to cover these cases.

Windows, on the other hand, does not make use of errno beyond the standard C library. Windows API calls typically report their errors via GetLastError.

When one considers network programming, the getaddrinfo family of functions uses its own set of error codes (EAI_...) on POSIX, but shares the GetLastError() "namespace" on Windows. Programs that integrate other libraries (for SSL, regular expressions, or whatever) will encounter other categories of error code.

Programs should be able to manage these error codes in a consistent manner. I'm especially concerned with enabling composition of operations to create higher-level abstractions. Combining system calls, getaddrinfo, SSL and regular expressions into one API should not force the user of that API to deal with an explosion of error code types. The addition of a new error source to the implementation of that API should not change the interface.

Be user-extensible

Users of the standard library need to be able to add their own error sources. This ability may just be used to integrate a third-party library, but is also tied in with the desire to create higher-level abstractions. When developing a protocol implementation such as HTTP, I want to be able to add a set of error codes corresponding to the errors defined in the RFC.

Preserve the original error code

This was not one of my original goals: my thinking was that the standard would provide a set of well-known error codes. If a system operation returned an error, it was the responsibility of the library to translate the error into a well-known code (if such a mapping made sense).

Fortunately, someone showed me the error of my ways. Translating an error code discards information: the error returned by the underlying system call is lost. This may not be a big deal in terms of program control flow, but it matters a lot for program supportability. There is no doubt that programmers will use a standardised error code object for logging and tracing, and the original error may be vital in diagnosing problems.

This final principle segues nicely into my topic for part 2: error_code vs error_condition. Stay tuned.


Anonymous said...

excellent article !

This is also good material for your book :)


Unknown said...

I really appreciate this content and discussion about error handling.

It looks like this subject is the least commented when it comes to talk about C++ new features. That's sad.

I've checked a bunch of recent books and it's rare to have any mention of error_condition for example.

Gryffin said...

std::system_error is the type of the exception thrown by various library functions (typically the functions that interface with the OS facilities.

Susan said...

View stories of any user anonymously. Pictame2 pictame. The more Instagram followers a person has the more popular they will be on this site.

Unknown said...

온라인카지노 I like this website very much, Its a rattling nice position to read and get information.

Unknown said...

We absolutely love your blog and find almost all of your post’s to be just what I’m looking for.
Does one offer guest writers to write content for you personally?
I wouldn’t mind publishing a post or elaborating on a number of the subjects you write with regards to here.

Again, awesome web log! 카지노사이트

Unknown said...

토토사이트 Hey There. I found your weblog using msn. This is an extremely smartly
written article. I’ll be sure to bookmark it and return to learn extra of your helpful information. Thanks for the post.
I’ll certainly return.

Unknown said...

Great goods from you, man. I have understand your stuff previous to and you are just extremely fantastic. I really like what you’ve acquired here, really like what you are saying and the way in which you say it. You make it enjoyable and you still care for to keep it smart. I cant wait to read far more from you. This is really a great site. 토토사이트

UFABET1688 said...

Thanks a lot for sharing this with all people you actually know what you're speaking approximately! Bookmarked. Please additionally visit my web site =). We may have a link alternate arrangement among us. ufabet

Anveshj said... is a private IP address used to login the admin panel of a router. 192.168.l.l is pre-specified by the router companies as the default gateway address and can be used to make different changes to the router’s settings.

UFABET1688 said...

Much obliged to you for your post, I search for such article along time, today I discover it at long last. this post give me heaps of prompt it is extremely helpful for me. ยูฟ่า168 said... is a private IP address used to login the admin panel of a router. 192.168.l.l is the host address to change default router settings.

Tom said...

Hey guys! If is wish to be the best with essay and dont know he excellent service for it check this rewrite essay service and go for it! This is it guys! This you chacnec so go fot it and be the best! Enjoy!

Majortotosite Pro said...

I got this web site from my friend who informed me regarding this website and at the moment this time I am visiting
this web page and reading very informative content here. 토토사이트

Racesite Pro said...

I blog quite often and I seriously thank you for your content. The article has really peaked my interest. I'm going to bookmark your site and keep checking for new information about once per week.
I opted in for your Feed too. 온라인경마

Totopick Pro said...

Howdy terrific blog! Does running a blog like this take a massive amount work? I have virtually no understanding of coding however I had been hoping to start my
own blog soon. 토토

메이저안전놀이터 said...

That's a great article! The neatly organized content is good to see. Can I quote a blog and write it on my blog? My blog has a variety of communities including these articles. Would you like to visit me later? 메이저안전놀이터

pg mega said...

Big Bad Wolf เกมสล็อต หมาป่า วายร้าย บิ้กแบดวูฟ เมก้าเวย์สล็อต เกมสล็อตลูกหมูสามตัว ที่มาในธีมสุนัขป่าไล่ขย้ำหมูในบ้านฟาง เป็นเกมทดสอบเล่นสล็อต Quickspin Slot มีภาพกราฟฟิคที่สวยสดงดงาม

Pg slot said...

There are many different games to choose from.
kingmaker ติดต่อ

Igoalplus said...

I really enjoyed your blog Thanks for sharing such an informative post.
cq9 slot ดาวน์โหลด