www.digitalmars.com         C & C++   DMDScript  

D - Exception specification?

reply "John Carney" <john.carney pacific.net.au> writes:
What about exception specification? Bjarne's 4th biggest mistake was not
making exception specification mandatory in C++ right from the get-go.

Cheers,
John Carney.
Aug 17 2001
next sibling parent reply "Walter" <walter digitalmars.com> writes:
John Carney wrote in message <9ljd0j$1j66$1 digitaldaemon.com>...
What about exception specification? Bjarne's 4th biggest mistake was not
making exception specification mandatory in C++ right from the get-go.

Cheers,
John Carney.

D ditches the whole exception specification thing. It inhibits code reuse and it is just plain annoying. Not that I have any opinion about it or anything <g>.
Aug 18 2001
next sibling parent reply "John Carney" <john.carney pacific.net.au> writes:
"Walter" <walter digitalmars.com> wrote in message
news:9lml50$10vj$1 digitaldaemon.com...
 John Carney wrote in message <9ljd0j$1j66$1 digitaldaemon.com>...
What about exception specification? Bjarne's 4th biggest mistake was not
making exception specification mandatory in C++ right from the get-go.

Cheers,
John Carney.

D ditches the whole exception specification thing. It inhibits code reuse

My experience when doing a stint of Java development a few years back was precisely the opposite.
 and it is just plain annoying.

Yeah, and so are compiler warnings, design-by-contract, type safety and countless other panty-waister schemes designed to get in the way of *real* programmers. Don't know why you're bothering with all this "D" business. We should all go back to pre-C++ era C compilers.
 Not that I have any opinion about it or
 anything <g>.

I see your opinion and raise you... ;-)
Aug 18 2001
parent reply "John Carney" <john.carney pacific.net.au> writes:
<snip>

 D ditches the whole exception specification thing. It inhibits code


 My experience when doing a stint of Java development a few years back was
 precisely the opposite.

 and it is just plain annoying.

Yeah, and so are compiler warnings, design-by-contract, type safety and countless other panty-waister schemes designed to get in the way of *real* programmers. Don't know why you're bothering with all this "D" business.

 should all go back to pre-C++ era C compilers.

Seriously Walter, you've got it right on so many other fronts, I'd really like you to reconsider your stance on this one. Think of it this way: if it is decided five years down the track that rigid exception specification is, after all, a good thing, you're going to break an awful lot of code if you try to tack it onto the language. On the other hand, if we in the pro-specification camp turn out to be wrong, then relaxing the rules isn't going to render anybody's code base inoperable. Cheers, John Carney.
Aug 19 2001
next sibling parent reply "Bradeeoh" <bradeeoh crosswinds.net> writes:
 Seriously Walter, you've got it right on so many other fronts, I'd really
 like you to reconsider your stance on this one. Think of it this way: if

 is decided five years down the track that rigid exception specification

 after all, a good thing, you're going to break an awful lot of code if you
 try to tack it onto the language. On the other hand, if we in the
 pro-specification camp turn out to be wrong, then relaxing the rules isn't
 going to render anybody's code base inoperable.

 Cheers,
 John Carney.

I agree with John on this. Like him, I learned better from a stint in Java development. First off, to elaborate on the Java model, there are two base types of exceptions. Any exception derived from "Exception" is forced to be delcared as throws in a function and you must catch it. This, you claim, Walter, is annoying, but its also invaluable for clean, safe code. Derivitives of RuntimeException do NOT have to be caught (but if they're not, the program exits with an error message ) Learning the subtles of whether to make your custom exception an Exception derivitive or a RuntimeException derivitive turns out to be an art when you start developing HUGE programs. But, other point to add onto Johns about how it would be better to make the rules stricter now then relax them later if we're proven wrong, is that anyone who DOESN'T like exception specification can just use runtime exceptions for their own custom code. (Built in normal exceptions would, of course, still have to be caught, but there's a REASON that they're thrown...) Call me an academic, but I think that's how it should be. ;) -Brady
Aug 19 2001
parent reply Charles Hixson <charleshixsn earthlink.net> writes:
I find exceptions to be quite valuable.  They need to be able to throw 
messages.  They also need to be "boundable", so that a method can 
guarantee that it won't propagate certain exceptions, even if a call 
that it makes throws it.

I don't know whether it matters whether this is done by specifying which 
exceptions it will pass, or which it won't pass.  The Java approach 
works pretty well.  (And it *is* annoying.)  I've never seen an example 
of a language where you guaranteed what you wouldn't throw, so I don't 
know how that would work.

I do know that Eiffel's preconditions/postconditions can be rather 
annoying.  A lot of the time I would like to throw an error condition to 
the calling routine, but this appears to be very discouraged by the 
Eiffel model.  It seems to want all problems to be handled locally.  So 
(current design problem) if I'm trying to insert a record into a locked 
list, Eiffel's answer is, well, you should have asked first.  You should 
have checked for EOF before you tried to read the file.  A reasonable 
choice.  Handle errors by preventing their occurance.  But sometimes it 
can be difficult to do this properly, and then you get run-time 
assertion errors.  Not good.  And no easy way to "catch and handle" them.

Ada may have a better approach here.  And Java's approach is pretty good.

One thing that needs to be clear:  Is an exception for handling an 
expectable error?  What's the run-time cost of handling an exception? 
This isn't always easy to find out, and it could have a big effect on 
how they would be used.  (Someone once told me that it took 1000 times 
as long to process an exception as to process a branch.  If this is 
true, then using them for "exceptional case" handling is ... less 
desireable.
Aug 20 2001
next sibling parent reply "John Carney" <john.carney pacific.net.au> writes:
"Charles Hixson" <charleshixsn earthlink.net> wrote in message
news:3B816D1F.80309 earthlink.net...

<snip>

 One thing that needs to be clear:  Is an exception for handling an
 expectable error?  What's the run-time cost of handling an exception?
 This isn't always easy to find out, and it could have a big effect on
 how they would be used.  (Someone once told me that it took 1000 times
 as long to process an exception as to process a branch.  If this is
 true, then using them for "exceptional case" handling is ... less
 desireable.

AFAIK the big cost in exception handling is cleaning up the stack. As an aside, I do recall reading somewhere that in Java, the following code: for (i = 0 ; i != anArray.length ; i++) doSomething(anArray[i]) ; could be written faster as: try { i = 0 ; while (true) doSomething(anArray[i++]) ; } catch (ArrayBoundsException &x) {} Don't quote me on that - it was a long time ago and may be complete bollocks. Cheers, John.
Aug 21 2001
next sibling parent reply Russell Bornschlegel <kaleja estarcion.com> writes:
John Carney wrote:
 As an aside, I do recall reading somewhere that in Java, the following code:
 
     for (i = 0 ; i != anArray.length ; i++)
         doSomething(anArray[i]) ;
 
 could be written faster as:
 
     try
         {
         i = 0 ;
         while (true)
             doSomething(anArray[i++]) ;
         }
     catch (ArrayBoundsException &x)
         {}
 
 Don't quote me on that - it was a long time ago and may be complete
 bollocks.

That doesn't seem plausible to me, but I'll confess total ignorance of the JVM. In any case, the time savings wouldn't be worth it: you'd get fired at the next code review. -RB
Aug 21 2001
parent reply Dan Hursh <hursh infonet.isl.net> writes:
Russell Bornschlegel wrote:
 
 John Carney wrote:
 As an aside, I do recall reading somewhere that in Java, the following code:

     for (i = 0 ; i != anArray.length ; i++)
         doSomething(anArray[i]) ;

 could be written faster as:

     try
         {
         i = 0 ;
         while (true)
             doSomething(anArray[i++]) ;
         }
     catch (ArrayBoundsException &x)
         {}

 Don't quote me on that - it was a long time ago and may be complete
 bollocks.

That doesn't seem plausible to me, but I'll confess total ignorance of the JVM. In any case, the time savings wouldn't be worth it: you'd get fired at the next code review. -RB

Actually, I'm scared. It makes sense to me. In the first case you are bounds checking twice each iteration. Once in the for expression and once in the array access. In the second one, you check once, and there doesn't appear to be much (or any) of a stack clean up. Beside I don't think java deallocates immediately in this case. Provided that anArray.length is large enough this make perfect sense. It must be time to sleep. Dan
Aug 23 2001
parent reply Russ Lewis <russ deming-os.org> writes:
Dan Hursh wrote:

 Russell Bornschlegel wrote:
 John Carney wrote:
 As an aside, I do recall reading somewhere that in Java, the following code:

     for (i = 0 ; i != anArray.length ; i++)
         doSomething(anArray[i]) ;

 could be written faster as:

     try
         {
         i = 0 ;
         while (true)
             doSomething(anArray[i++]) ;
         }
     catch (ArrayBoundsException &x)
         {}

 Don't quote me on that - it was a long time ago and may be complete
 bollocks.

That doesn't seem plausible to me, but I'll confess total ignorance of the JVM. In any case, the time savings wouldn't be worth it: you'd get fired at the next code review. -RB

Actually, I'm scared. It makes sense to me. In the first case you are bounds checking twice each iteration. Once in the for expression and once in the array access.

This isn't necessarily true. A good optimizer compiler should (not saying would - just should) know that you are doing the bounds checking against the array length and thus it should disable its bounds checking code on that array access. Thus, if you are writing performance critical code - and you are using a mature D optimizer, right? - the first example should actually be as fast as the second, and it should be smaller, as the compiler does not have to include exception throwing/catching code.
Aug 24 2001
parent reply Russell Bornschlegel <kaleja estarcion.com> writes:
Russ Lewis wrote:
 
 Dan Hursh wrote:
 
 Russell Bornschlegel wrote:
 John Carney wrote:
 As an aside, I do recall reading somewhere that in Java, the following code:

     for (i = 0 ; i != anArray.length ; i++)
         doSomething(anArray[i]) ;

 could be written faster as:

     try
         {
         i = 0 ;
         while (true)
             doSomething(anArray[i++]) ;
         }
     catch (ArrayBoundsException &x)
         {}

 Don't quote me on that - it was a long time ago and may be complete
 bollocks.

That doesn't seem plausible to me, but I'll confess total ignorance of the JVM. In any case, the time savings wouldn't be worth it: you'd get fired at the next code review. -RB

Actually, I'm scared. It makes sense to me. In the first case you are bounds checking twice each iteration. Once in the for expression and once in the array access.

This isn't necessarily true. A good optimizer compiler should (not saying would - just should) know that you are doing the bounds checking against the array length and thus it should disable its bounds checking code on that array access. Thus, if you are writing performance critical code - and you are using a mature D optimizer, right?

No, the D optimizer doesn't work so well on Java. -R
Aug 24 2001
parent Russ Lewis <russ deming-os.org> writes:
Russell Bornschlegel wrote:

 Russ Lewis wrote:
 Dan Hursh wrote:

 Russell Bornschlegel wrote:
 John Carney wrote:
 As an aside, I do recall reading somewhere that in Java, the following code:

     for (i = 0 ; i != anArray.length ; i++)
         doSomething(anArray[i]) ;

 could be written faster as:

     try
         {
         i = 0 ;
         while (true)
             doSomething(anArray[i++]) ;
         }
     catch (ArrayBoundsException &x)
         {}

 Don't quote me on that - it was a long time ago and may be complete
 bollocks.

That doesn't seem plausible to me, but I'll confess total ignorance of the JVM. In any case, the time savings wouldn't be worth it: you'd get fired at the next code review. -RB

Actually, I'm scared. It makes sense to me. In the first case you are bounds checking twice each iteration. Once in the for expression and once in the array access.

This isn't necessarily true. A good optimizer compiler should (not saying would - just should) know that you are doing the bounds checking against the array length and thus it should disable its bounds checking code on that array access. Thus, if you are writing performance critical code - and you are using a mature D optimizer, right?

No, the D optimizer doesn't work so well on Java.

LOL! Ok, fair enough. It's just whenever I see some discussion here, I think of its applicability to D :p
Aug 24 2001
prev sibling next sibling parent Charles Hixson <charleshixsn earthlink.net> writes:
John Carney wrote:
 "Charles Hixson" <charleshixsn earthlink.net> wrote in message
 news:3B816D1F.80309 earthlink.net...
 
 <snip>
...
 AFAIK the big cost in exception handling is cleaning up the stack.
 
 As an aside, I do recall reading somewhere that in Java, the following code:
 
     for (i = 0 ; i != anArray.length ; i++)
         doSomething(anArray[i]) ;
 
 could be written faster as:
 
     try
         {
         i = 0 ;
         while (true)
             doSomething(anArray[i++]) ;
         }
     catch (ArrayBoundsException &x)
         {}
 
 Don't quote me on that - it was a long time ago and may be complete
 bollocks.
 
 Cheers,
 John.
 

longer, but that's because it's a trivial example. If one is doing this, how does one decide which is the better choice? It doesn't seem to be documented anywhere. Probably it's "implementation dependant", but there don't even seem to be any reasonable guidelines. Is it reasonable to handle an EOF detect by exception? How long a file is required before that's the faster way to do things, and is there some other reason why it's undesireable? Different languages seem to have different assumptions about this, and it tends to be quite a pain to figure it out in each one. (Java is one of the more open about this, and is also relatively tolerant of exceptions.)
Aug 21 2001
prev sibling parent "Walter" <walter digitalmars.com> writes:
John Carney wrote in message <9ltbbg$20mh$1 digitaldaemon.com>...
As an aside, I do recall reading somewhere that in Java, the following

    for (i = 0 ; i != anArray.length ; i++)
        doSomething(anArray[i]) ;

could be written faster as:

    try
        {
        i = 0 ;
        while (true)
            doSomething(anArray[i++]) ;
        }
    catch (ArrayBoundsException &x)
        {}

Don't quote me on that - it was a long time ago and may be complete
bollocks.

The reason for that is because inside the loop there's a check for the array bounds in addition to the check on the loop bounds. Eliminating one of the redundant checks can doubled the speed of the loop. In D, array bounds checking can be turned on and off (unlike Java, which guarantees it is on), so the above loop is invalid D.
Sep 23 2001
prev sibling next sibling parent reply Christophe de Dinechin <descubes earthlink.net> writes:
Charles Hixson wrote:

  (Someone once told me that it took 1000 times
 as long to process an exception as to process a branch.

Depends on the implementation, but that might be a good lower bound for the simplest case :-/ Christophe
Aug 22 2001
next sibling parent "John Carney" <john.carney pacific.net.au> writes:
"Christophe de Dinechin" <descubes earthlink.net> wrote in message
news:3B841CA1.8A08E9E6 earthlink.net...
 Charles Hixson wrote:

  (Someone once told me that it took 1000 times
 as long to process an exception as to process a branch.

Depends on the implementation, but that might be a good lower bound for

 simplest case :-/

Bollocks!
Aug 23 2001
prev sibling parent "Richard Krehbiel" <rich kastle.com> writes:
"Christophe de Dinechin" <descubes earthlink.net> wrote in message
news:3B841CA1.8A08E9E6 earthlink.net...
 Charles Hixson wrote:

  (Someone once told me that it took 1000 times
 as long to process an exception as to process a branch.

Depends on the implementation, but that might be a good lower bound for

 simplest case :-/

With today's C++ implementations, throw/catch is pretty quick. But that's because, upon entry, each C++ function sets up exception handling stuff in the stack frame, and removes it at exit. But some application markets don't like having to pay this "penalty" when so few exceptions are actually processed. To try to appease these folk, the C++ language spec says that exceptions are the exception (yuk yuk), not the norm, and so exception handling may be arbitrarily complex. This would (theoretically) allow an implementation to do thrown exceptions the *hard* way, by comparing stack frame addresses against a link map to find exception handlers, rather than require each function to run exception set-up and take-down even when no exceptions are thrown. -- Richard Krehbiel, Arlington, VA, USA rich kastle.com (work) or krehbiel3 home.com (personal)
Aug 23 2001
prev sibling parent "Walter" <walter digitalmars.com> writes:
Charles Hixson wrote in message <3B816D1F.80309 earthlink.net>...
One thing that needs to be clear:  Is an exception for handling an
expectable error?  What's the run-time cost of handling an exception?
This isn't always easy to find out, and it could have a big effect on
how they would be used.  (Someone once told me that it took 1000 times
as long to process an exception as to process a branch.  If this is
true, then using them for "exceptional case" handling is ... less
desireable.

The runtime penalty for throwing an exception is large. Therefore, they should only be used for *exceptional errors*. Sometimes this requires rethinking what an error is. For example, polling a device in a loop to see if it is ready yet is not an error if it is not ready. It is only an error if it is *assumed* to be ready.
Sep 23 2001
prev sibling parent reply "Walter" <walter digitalmars.com> writes:
I'm going to rethink it. I do read all of the arguments <g>. -Walter

John Carney wrote in message <9lntkc$1p07$1 digitaldaemon.com>...
Seriously Walter, you've got it right on so many other fronts, I'd really
like you to reconsider your stance on this one. Think of it this way: if it
is decided five years down the track that rigid exception specification is,
after all, a good thing, you're going to break an awful lot of code if you
try to tack it onto the language. On the other hand, if we in the
pro-specification camp turn out to be wrong, then relaxing the rules isn't
going to render anybody's code base inoperable.

Cheers,
John Carney.

Sep 23 2001
parent "John Carney" <john.carney pacific.net.au> writes:
 I'm going to rethink it. I do read all of the arguments <g>. -Walter

Can't ask fairer than that :-) Cheers, John Carney.
Sep 23 2001
prev sibling parent reply "kaffiene" <kaffiene xtra.co.nz> writes:
"Walter" <walter digitalmars.com> wrote in message
news:9lml50$10vj$1 digitaldaemon.com...
 John Carney wrote in message <9ljd0j$1j66$1 digitaldaemon.com>...
What about exception specification? Bjarne's 4th biggest mistake was not
making exception specification mandatory in C++ right from the get-go.

Cheers,
John Carney.

D ditches the whole exception specification thing. It inhibits code reuse and it is just plain annoying. Not that I have any opinion about it or anything <g>.

I 100% disagree with this. I think practical experience in dealing with exceptions in Java as opposed to C++ proves the opposite to be true. Exception specification is a major tool for creating code that handles errors gracefully. The C++ approach more often than not leads to code that leaves all exceptions to a try - catch block in main, where it is too far removed from the problem to do anything usefull with it other than bomb. The Java approach forces programmers to think about exceptions and deal with them properly (even if they decide to delegate resopnsibility, it is an explicit decision and a dscision which is visible to client code / other programmers.) Peter.
Aug 18 2001
parent reply Russ Lewis <russ deming-os.org> writes:
kaffiene wrote:

 "Walter" <walter digitalmars.com> wrote in message
 news:9lml50$10vj$1 digitaldaemon.com...
 John Carney wrote in message <9ljd0j$1j66$1 digitaldaemon.com>...
What about exception specification? Bjarne's 4th biggest mistake was not
making exception specification mandatory in C++ right from the get-go.

Cheers,
John Carney.

D ditches the whole exception specification thing. It inhibits code reuse and it is just plain annoying. Not that I have any opinion about it or anything <g>.

I 100% disagree with this. I think practical experience in dealing with exceptions in Java as opposed to C++ proves the opposite to be true. Exception specification is a major tool for creating code that handles errors gracefully. The C++ approach more often than not leads to code that leaves all exceptions to a try - catch block in main, where it is too far removed from the problem to do anything usefull with it other than bomb. The Java approach forces programmers to think about exceptions and deal with them properly (even if they decide to delegate resopnsibility, it is an explicit decision and a dscision which is visible to client code / other programmers.)

<rabid-opinion> Not having exception specifications is like not checking the return code on malloc on the theory that "hey, a segfault will clean it up". The C++ solution, having catch(...) speciifcations all over, is like calling exit() every time *any* function fails. </rabid-opinion>
Aug 18 2001
parent "John Carney" <john.carney pacific.net.au> writes:
"Russ Lewis" <russ deming-os.org> wrote in message
news:3B7F3AEA.4E79C687 deming-os.org...

<snip>

 <rabid-opinion>

 Not having exception specifications is like not checking the return code

 malloc on the theory that "hey, a segfault will clean it up".

 The C++ solution, having catch(...) speciifcations all over, is like

 exit() every time *any* function fails.

 </rabid-opinion>

:-) Or like never freeing memory on the basis that it'll get released when the application exits. Or like never closing file handles because the system will close them when the process dies. Cheers, John.
Aug 19 2001
prev sibling parent reply Russ Lewis <russ deming-os.org> writes:
It occurs to me that strict exception specification might make the exception
handling code less costly and complex (from the compiler perspective).  I
assume that unlimited exceptions (like in C++) means that the compiler has
to implement some sort of runtime type identification to compare the thrown
type to the list of caught types.  It seems that with strict specification,
the exceptions could by specified by an ordered numbering.  That is, when
you throw an exception, you throw both a value (pointer, I assume) and an
integer; the integer corresponds with the exception type's order in your
function declaration.  Thus:

void foo() throws A,B,C;

means that if foo throws A, the type parameter will be set to 0, B it is 1,
C it is 2.  The catch block can look up these values.  Consider:

void bar() throws A,C; // calls foo()

In the catch block in bar(), if it sees the type as 0, then it just rethrows
it.  If the type is 2, it changes the type to 1 and rethrows (since C is
exception 1 in its declaration).  If the type is 1, then it jumps to the
handler code.

This seems like something that could be handled very simply with a
compiler-implemented switch block.



My understanding of exceptions is like that of garbage collection; I
understand the concept but don't know how it is implemented, so maybe I'm
totally confused.  Thoughts?

--
The Villagers are Online! http://villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]
Sep 28 2001
parent "Walter" <walter digitalmars.com> writes:
"Russ Lewis" <russ deming-os.org> wrote in message
news:3BB46A58.88D44384 deming-os.org...
 My understanding of exceptions is like that of garbage collection; I
 understand the concept but don't know how it is implemented, so maybe I'm
 totally confused.  Thoughts?

The best way to understand it is to write some EH code in C++, compile it, and run the output through OBJ2ASM. D implements it the same way. Also, there will only be EH overhead in D for functions that have try blocks in them.
Dec 26 2001