开发者

Exceptions vs. errno

As a C programmer, I don't ha开发者_如何学Cve much experience with exceptions. I'm rather used to errno as a means of communicating errors across several function calls. That having said, I don't see the distinguishing feature of exceptions, so...

What is the fundamental difference between exceptions and using errno?


There are so many differences here it's hard to say where to start.

First of all, errno as used in C is a global variable; this means every routine that calls an errno-setting subroutine must check errno before performing any other work, if it cares about correctness. Luckily enough, errno is threadsafe.

C++ exceptions automatically unwind up the call stack until they find a function prepared to handle the fault. This means that in most cases users don't have to explicitly check every call for an error; instead they can collect error returns in one place. C++ exceptions can contain values other than integers, unlike errno.


You can casually ignore errno. Exceptions must be dealt with.

Of course I've seen my share of:

try {
   // something
}
catch( ... ) {
   // nothing
}
// continue as if nothing happened

and (Java)

try {
   // something
}
catch( Throwable t ) {
   // nothing
}
// continue as if nothing happened

BUT at least that kinda jumps out at you when you're plowing through someone else's mess.


I feel compelled to point out that writing correct programs in the face of exceptions is not easy. You do well to do some research on the subject, perhaps starting with Guru of the Week. Just look for the word exception.


1) Exceptions can be anything, not just an integer. So the data communicated is different.

2) Exceptions do non-local control flow, so you don't have to check at every level in the way that in practice with errno, you also return a value that indicates error and every caller checks for errors and bails out early if one has occurred. Conversely, error returns do local control flow, so you can always see exactly when errors are propagated through a given piece of code. This difference radically changes coding style. So the means of communicating are different too.


To me, the most important difference is that errno is easily ignored, whereas exceptions are pretty hard to ignore - the program will terminate if you end up ignoring them... Plus, exceptions are (well, should be) objects, so you can carry more useful information.

The other, very important difference is that exceptions can easily be handled at the point where the software can actually make an informed decision how to handle the problem, which is usually several levels up the call stack. That's not that easy to do with error codes.


One pattern which I've found useful on embedded systems is to have an error flag for each stream, but provide that an I/O operation which is attempted when the flag is set will fail immediately. Thus, code can do something like:

  pkt_type = tcp_getbyte(my_stream, timeout);
  pkt_length = tcp_getbyte(my_stream, timeout);
  pkt_length |= tcp_getbyte(my_stream, timeout) << 8;
  if (pkt_length < MAX_PACKET_LENGTH)
  {
    for (i=0; i<pkt_length; i++)
      buffer[i] = tcp_getbyte(my_stream, timeout);
  }
  if (!my_stream->error)
  {
    /* Do something with packet */
  }

If one attempt to get a byte times out, succeeding attempts will fail unconditionally, returning zero. It's not necessary to check every operation for failure; if something goes wrong, the system will end up behaving roughly as though tcp_getbyte() had thrown an exception, just not quite as fast.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜