Topic: why no compile time enforcment?


Author: James Kuyper <kuyper@wizard.net>
Date: 2000/09/20
Raw View
David Abrahams wrote:
>
> "James Kuyper" <kuyper@wizard.net> wrote in message
> news:39C80546.2336EB2@wizard.net...
...
> Not to beat a dead nag, but just to be absolutely explicit: that quote
> doesn't make it clear that he's also talking about abolishing the current
> runtime behavior of exception-specifications. In other words, a completely
> different language feature.

Not really. What's going on is that if compile-time enforcement of
exception specifications were required, code which could ever possibly
trigger the behavior you're talking about would not be well-formed. It
would be more than faintly ridiculous for the standard to simultaneously
prohibit code that contains a specific feature, yet mandate how such
code should work.

If such code were prohibited, the even if the standard did continue to
mandate such behavior, a conforming implementation wouldn't have to
satisfy that mandate, under the as-if rule.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "David Abrahams" <abrahams@mediaone.net>
Date: 2000/09/18
Raw View
"Anders Pytte" <anders@milkweed.com> wrote in message
news:B5EAF619.C6F7%anders@milkweed.com...

> I meant that the way exception specifications are enforced, as specified
by
> the C++ standard, is half-baked, as acknowledged by at least some members
of
> the standards committee.
>
> So once again, contrary to the position put forth in the post to which I
was
> responding, efficiency is not an argument against static enforcement of
> exception specifications, only against runtime enforcement as required by
> the C++ standard.

Oh, I see now. You're talking about a completely different hypothetical
language feature that doesn't exist in C++, but which has a similar (or
identical) syntax and completely different behavior. It is important that
you make that clear. Many people who claim to like exception-specifications
actually like the fantasy feature you're describing.

It might be nice to have that fantasy feature (though I have my doubts), but
it seems very unlikely that it could ever replace the feature we've got.
There are too many programs that rely on that runtime behavior.

-Dave


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James Kuyper <kuyper@wizard.net>
Date: 2000/09/19
Raw View
David Abrahams wrote:
...
> Oh, I see now. You're talking about a completely different hypothetical
> language feature that doesn't exist in C++, but which has a similar (or
> identical) syntax and completely different behavior. It is important that
> you make that clear. ...

I don't unstand why you're labeling it a "fantasy" feature. My best
guess would be that you're calling it a fantasy feature because it's not
currently part of the language, but that would imply that you have more
trouble understanding ordinary written english than seems plausible. The
title of the thread: "why no compile time enforcement?" makes it very
clear that he's aware that the feature he's asking about is not
currently part of the language.

My next guess is that you're trying to imply that it's unimplementable,
but I haven't seen any arguments to that effect on this thread. Some
disagreement on how much overhead it would cause, but no claims of
unimplementability.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "David Abrahams" <abrahams@mediaone.net>
Date: 2000/09/19
Raw View
"James Kuyper" <kuyper@wizard.net> wrote in message
news:39C6B585.83EF8787@wizard.net...
> David Abrahams wrote:
> ...
> > Oh, I see now. You're talking about a completely different hypothetical
> > language feature that doesn't exist in C++, but which has a similar (or
> > identical) syntax and completely different behavior. It is important
that
> > you make that clear. ...
>
> I don't unstand why you're labeling it a "fantasy" feature. My best
> guess would be that you're calling it a fantasy feature because it's not
> currently part of the language, but that would imply that you have more
> trouble understanding ordinary written english than seems plausible. The
> title of the thread: "why no compile time enforcement?" makes it very
> clear that he's aware that the feature he's asking about is not
> currently part of the language.

Normally, when people ask "why doesn't <language feature xxx> have <behavior
yyy>?" they are not talking about completely replacing the definition of
xxx. For example, the question recently came up, "why doesn't 'delete x'
cause x to be NULL?"  Nobody was talking about throwing out the existing
behavior of delete.

> My next guess is that you're trying to imply that it's unimplementable,
> but I haven't seen any arguments to that effect on this thread. Some
> disagreement on how much overhead it would cause, but no claims of
> unimplementability.

Not at all; I'm just trying to highlight that it is (except possibly for
syntax) completely orthogonal to the feature we have now. When people say
"exception-specifications" but they are talking about the fantasy, not
anything like what the standard calls "exception-specifications", it causes
lots of confusion. Then people make up harmful programming guidelines based
on the fantasy, for example, "Use exception-specifications on all your
functions to ensure program correctness".

semantically-precise-ly y'rs,
dave

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 2000/09/20
Raw View
David Abrahams wrote:
>
> "James Kuyper" <kuyper@wizard.net> wrote in message
> news:39C6B585.83EF8787@wizard.net...
...
> > I don't unstand why you're labeling it a "fantasy" feature. My best
> > guess would be that you're calling it a fantasy feature because it's not
> > currently part of the language, but that would imply that you have more
> > trouble understanding ordinary written english than seems plausible. The
> > title of the thread: "why no compile time enforcement?" makes it very
> > clear that he's aware that the feature he's asking about is not
> > currently part of the language.
>
> Normally, when people ask "why doesn't <language feature xxx> have <behavior
> yyy>?" they are not talking about completely replacing the definition of
> xxx. ...

>From the very start of this thread:

Anders Pytte wrote:
...
> Sorry to dig this up again. But when a colleague asked me, I could not
> remember the reason(s) why the standard committee chose not to include
> compile time enforcement of exception specifications.

That makes it very clear to me that was aware when he wrote it that the
standard does not call for compile-time enforcement of exception
specifications. It also suggests that he was in favor of compile-time
enforcement of exception specifications.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Ken Hagan" <K.Hagan@thermoteknix.co.uk>
Date: 2000/09/20
Raw View
"David Abrahams" <abrahams@mediaone.net> wrote in message
news:I_px5.6541$tn.76394@typhoon.ne.mediaone.net...
>
> It might be nice to have that fantasy feature (though I have
> my doubts), but it seems very unlikely that it could ever
> replace the feature we've got. There are too many programs
> that rely on that runtime behavior.

Bearing in mind that the current behaviour was an invention
of a fairly recent standard, that at least one quite popular compiler
doesn't support the feature at all, and that your
esteemed self and others regularly rail against ever going
near exception specs with a ten foot pole...

...it would be interesting to know just how many programs
actually depend on run-time ES.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "David Abrahams" <abrahams@mediaone.net>
Date: 2000/09/20
Raw View
"James Kuyper" <kuyper@wizard.net> wrote in message
news:39C80546.2336EB2@wizard.net...

> >From the very start of this thread:
>
> Anders Pytte wrote:
> ...
> > Sorry to dig this up again. But when a colleague asked me, I could not
> > remember the reason(s) why the standard committee chose not to include
> > compile time enforcement of exception specifications.
>
> That makes it very clear to me that was aware when he wrote it that the
> standard does not call for compile-time enforcement of exception
> specifications. It also suggests that he was in favor of compile-time
> enforcement of exception specifications.

Not to beat a dead nag, but just to be absolutely explicit: that quote
doesn't make it clear that he's also talking about abolishing the current
runtime behavior of exception-specifications. In other words, a completely
different language feature.

-Dave

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Tim McCarthy" <tfmccarthy@erols.com>
Date: 2000/09/17
Raw View
Andrew Koenig <ark@research.att.com> wrote in message
news:yu993dj3xbfd.fsf@europa.research.att.com...
> >> One reason is that doing so would have made it impossible for vendors
> >> to extend their implementations to make arithmetic overflows throw
> >> exceptions.
>
> >> For example:
>
> >> int sum(int x, int y) throw(Overflow, Underflow)
> >> {
> >> if (x > 0 && y > 0 && x > MAXINT - y)
> >> throw Overflow();
> >> if (x < 0 && y < 0 && x < MININT - y)
> >> throw Underflow();
> >> return x + y;
> >> }
>

<snip>

>
> Tim> I guess I don't get the question since this didn't add up to me. Why
would
> Tim> the compiler reject the program for overflow? It's one of the
exceptions
> Tim> that sum specifies it throws.
>
> The point is that if x+y overflows, the behavior is undefined.
> That means that the compiler is permitted to do absolutely anything
> at all, including throwing absolutely any exception at all.

I didn't think the behavior was underfined (1). Did I miss something?

I mistook the meaning of "...if the implementation throws an exception on
overflow..." I take that to mean that the implementation of the run-time
library may throw a overflow (== Overflow) exception at run time. Now the
library may or may not specify throwing the exception but, AFAICS, it
shouldn't affect the behavior of sum.

Just to be pedantic for safety sake, if x+y overflows then I presume that an
Overflow exception is generated. OTOH, if we're talking about the compiler
generating code for x+y that results in an arithmetic overflow but does not
generate the exception then I believe the compiler is faulty or there's an
error in the code if (x > 0 && y > 0 && x > MAXINT - y). i.e. the value
MAXINT is erroneous or the compiler generates significantly different code
for sematically equivalent statements.

>
> Now, suppose I want to compile this program on a compiler that
> happens to throw Arithmetic_error if integer addition overflows.
> Under static checking, wouldn't the compiler be justified in
> rejecting the program because it doesn't include Arithmetic_error
> in the list of exceptions that it might throw?

I don't think so. AFAIK, the exception specification doesn't limit the types
of exceptions that can be thrown in sum; just the types of exceptions that
can come from sum. So sum can throw 3 exception types: Overflow, Underflow,
and unexpected.

> The trouble is that as the author of the function, I know that it
> can't possibly throw such an exception, because I have checked
> the values of x and y beforehand.  Shouldn't I feel justified
> in writing such a program?

Force the condition...

void faulty(int x, int y)
{
    throw Arithmetic_error();
}

int sum(int x, int y) throw(Overflow, Underflow)
{
    faulty();
    return x+y;
}

void test()
{
    int x = 1;
    int y = 1;
    sum(x, y);
}

As I understand this, sum will mask the Arithmetic_error by transformation
into std::unexpected. A static check should flag the the call to faulty as
an unmatched exception and flag test as unhandled exception(s).

What I can't understand is that when I do the same transformation of your
example with that of the 14.6 I don't encounter any undefined behavior. 14.6
states that...

void f() throw (x2, x3)
{
    // stuff
}

is equivalent to

void f()
{
try
{
    // stuff
}
catch (x2) {throw;}
catch (x3) {throw;}
catch(...)
{
    std::unexpected();
}
}

If I apply the same transformation to the example,

int sum(int x, int y) throw(Overflow, Underflow)
{
if (x > 0 && y > 0 && x > MAXINT - y)
throw Overflow();
if (x < 0 && y < 0 && x < MININT - y)
throw Underflow();
return x + y;
}

I get

int sum(int x, int y) throw(Overflow, Underflow)
{
try
{
    if (x > 0 && y > 0 && x > MAXINT - y)
    throw Overflow();
    if (x < 0 && y < 0 && x < MININT - y)
    throw Underflow();
    return x + y;
}
catch(Overflow) {throw;}
catch(Underflow) {throw;}
catch(...)
{
    std::unexpected();
}
}

If x+y throws Overflow wouldn't it be properly handled?

--
Tim McCarthy
tfmccarthy@erols.com

(1) "The C++ Programming Language Special Edition", 14.6 "...If during
execution that function does something that tries to abrogate the guarantee,
the attempt will be transformed into a call of std::unexpected."

AFAIK, this is the essential principle underlying exceptions: An exception
specification restricts the types of exceptions that a function can throw.



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James Kanze <James.Kanze@dresdner-bank.de>
Date: 2000/09/17
Raw View
Andrew Koenig wrote:

> >> One reason is that doing so would have made it impossible for
> >> vendors to extend their implementations to make arithmetic
> >> overflows throw exceptions.

> >> For example:

> >> int sum(int x, int y) throw(Overflow, Underflow)
> >> {
> >> if (x > 0 && y > 0 && x > MAXINT - y)
> >> throw Overflow();
> >> if (x < 0 && y < 0 && x < MININT - y)
> >> throw Underflow();
> >> return x + y;
> >> }

> >> This function checks the values of x and y before adding them, so
> >> that it knows that computing x + y will not overflow.  However,
> >> if the implementation throws an exception on overflow, static
> >> checking will reject this program because x + y might throw an
> >> exception that the programmer (but not the compiler) knows can
> >> never occur.

> Tim> I guess I don't get the question since this didn't add up to
> me. Why would Tim> the compiler reject the program for overflow?
> It's one of the exceptions Tim> that sum specifies it throws.

> The point is that if x+y overflows, the behavior is undefined.  That
> means that the compiler is permitted to do absolutely anything at
> all, including throwing absolutely any exception at all.

> Now, suppose I want to compile this program on a compiler that
> happens to throw Arithmetic_error if integer addition overflows.
> Under static checking, wouldn't the compiler be justified in
> rejecting the program because it doesn't include Arithmetic_error in
> the list of exceptions that it might throw?

> The trouble is that as the author of the function, I know that it
> can't possibly throw such an exception, because I have checked the
> values of x and y beforehand.  Shouldn't I feel justified in writing
> such a program?  Or should I have to write

>         int sum(int x, int y) throw(Overflow, Underflow)
>         {
>             if (x > 0 && y > 0 && x > MAXINT - y)
>                 throw Overflow();
>             if (x < 0 && y < 0 && x < MININT - y)
>                 throw Underflow();
>             try {
>                 return x + y;
>             } catch(...) {
>                 // This cannot happen
>                 return 0;
>             }
>         }

> just so that I do not run afoul of a static check for a condition
> that I know can never happen?

There's an interesting point here.  IMHO, if static checking were
required, it would take away the right of the implementation to throw
an exception on overflow.  Let's face it, if I write x + y, and static
checking exists, I *must* know what (if anything) it can throw -- if
not, I can't effectively write any program without encapsulating every
addition in a try block.  The following program must be legal:

    int sum( int x , int y ) throw()
    {
        return x + y ;
    }

Or at least, it must be legal with some standards defined throw
clause; I certainly don't want to have to use #ifdef to change the
throw clause according to the implementation.

(Personally, I think that arithmetic overflow *should* throw a defined
exception.  At least C++ allows an implementation to do the right
thing, unlike some other languages which vaunt their safety.)

--
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Ken Hagan" <K.Hagan@thermoteknix.co.uk>
Date: 2000/09/17
Raw View
"Andrew Koenig" <ark@research.att.com> wrote in message
news:yu993dj3xbfd.fsf@europa.research.att.com...
>
> Or should I have to write

[snip ugly code]

> just so that I do not run afoul of a static check for
> a condition that I know can never happen?

In different contexts, C++ uses casts to inform the
compiler that the programmer thinks s/he knows more
about the situation than meets the eye. Most of these
casts are "at your own risk".

That looks like what we need here. We need to be able
to say, "You should assume this won't throw. If it does
then that's my problem, not yours.".

So would anyone like to suggest a syntax for casting
away (parts of) a throw specification?



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Tim McCarthy" <tfmccarthy@erols.com>
Date: 2000/09/17
Raw View
Boy, did I miss this one!

Andrew Koenig <ark@research.att.com> wrote in message
news:yu993dj3xbfd.fsf@europa.research.att.com...

<snip>

>
> The trouble is that as the author of the function, I know that it
> can't possibly throw such an exception, because I have checked
> the values of x and y beforehand.  Shouldn't I feel justified
> in writing such a program?  Or should I have to write
>
> int sum(int x, int y) throw(Overflow, Underflow)
> {
>     if (x > 0 && y > 0 && x > MAXINT - y)
>         throw Overflow();
>     if (x < 0 && y < 0 && x < MININT - y)
>         throw Underflow();
>     try {
>         return x + y;
>     } catch(...) {
> // This cannot happen
> return 0;
>     }
> }
>
> just so that I do not run afoul of a static check for a condition
> that I know can never happen?
>

Also, Daniel James' post has a nice summary as well.

The problem is that the compiler won't be able to detect the logical check
of the exception conditions and should flag the code as in error. As Mr.
Koenig indicates, a change in the expression of the function would be
required to satisfy the compiler. IMO, such a restriction on program
expression is cause enough to reject the feature for the standard.

As for me, I get another lesson on reading comprehension.

--
Tim McCarthy
tfmccarthy@erols.com



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: 2000/09/17
Raw View
In article <VA.00000393.81c27973@nospam.demon.co.uk>, Daniel James
<internet@nospam.demon.co.uk> writes
>I think that the aim should be to have code that compiles cleanly with
>rigorous compile-time checking of thow specs, and then have the option
>to turn off the *runtime* checks altogether. After all, there's no point
>in checking code at runtime for an exception that we already know it
>can't throw (which I think is the same thing as Andrew was saying,
>though in a rather different context).

We have, IMO, a chicken and egg problem. Because of the potential
runtime problems many programmers do not attach ES to their code.  This
means that code that relies on the work of anyone else (most code, IOWs)
cannot be fully checked at compile time (well it can but it will throw
up a multitude of problems).

What makes the problem worse is that I do not know of anyway to specify
that compilers must provide an option to switch of ES use. Unless we can
rely on being able to switch it off, I think the chance that many
programmers will add ESs to their functions is very small.

I think this is a place where leaving something as a QoI issue fails. If
it were possible I would like to have runtime enforcement off by default
with a standard mechanism (perhaps a special header) for switching them
on.  That way everyone could feel happy that they did not need to pay
for ES unless they chose to. This would be sort of like assert and
NDEBUG except that it cannot be done that simply, but would require
compiler magic.


Francis Glassborow      Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "David Abrahams" <abrahams@mediaone.net>
Date: 2000/09/17
Raw View
"Anders Pytte" <anders@milkweed.com> wrote in message
news:B5E66D74.C3DC%anders@milkweed.com...
> I'm having a little trouble parsing what you wrote, but I think I can
> summarize as follows:
>
> The compiler is able to determine which exceptions are possible within any
> specific try block, and so, in the cases where no exceptions are possible,
> or where the possible exceptions are not handled by the catch statements
> associated with that try block, that try-catch could be omitted by the
> compiler.

So far so good.

> The use of exception specifications can increase the likely hood that the
> compiler can make the above optimization. However, compilers may not
bother
> making the optimization, the improvement in efficiency may not be
> significant, and the above conditions may not occur frequently enough to
> make the optimization meaningful.

Or you may only get a space (not speed) optimization - very likely if any
optimization happens at all.

And you're leaving out half of the story. Exception specifications also have
a cost (in speed, space, or both) whenever the compiler cannot or does not
verify that they are statically satisfied. In real programs with real
compilers, this is common.

> In any case - and I need to emphasize this - the main benefits of
exception
> specifications are not related to efficiency, but to system correctness. I
> have never claimed otherwise.

I'm not going to touch that one with a ten-foot pole. Remember, Lois is
watching me...

> One cannot argue against exception specifications in general by claiming
> that they have runtime costs.

No, only with respect to particular compilers.

> That was the position of the post which
> started this exchange. This argument only comes up in relationship to the
> current half-baked C++ implementation of .

Please don't generalize that way. The implementation of the feature is not
specified by the language. There are a few compilers out there that have
very good implementations of exception specifications, for example Sun and
IBM.

-Dave


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Anders Pytte <anders@milkweed.com>
Date: 2000/09/18
Raw View
in article mNcw5.87444$_s1.1107760@typhoon.ne.mediaone.net, David Abrahams
at abrahams@mediaone.net wrote on 9/17/00 11:45 AM:

> And you're leaving out half of the story. Exception specifications also have
> a cost (in speed, space, or both) whenever the compiler cannot or does not
> verify that they are statically satisfied. In real programs with real
> compilers, this is common.

Because that is not an issue in the context of my statements, which was what
exception specifications would be like if static enforcement was required.

> "Anders Pytte" <anders@milkweed.com> wrote in message
> news:B5E66D74.C3DC%anders@milkweed.com...

>> That was the position of the post which
>> started this exchange. This argument only comes up in relationship to the
>> current half-baked C++ implementation of .
>
> Please don't generalize that way. The implementation of the feature is not
> specified by the language. There are a few compilers out there that have
> very good implementations of exception specifications, for example Sun and
> IBM.

I figured i would get in trouble for my imprecise language, but was too lazy
to fix it, thinking I would be understood anyway.

I meant that the way exception specifications are enforced, as specified by
the C++ standard, is half-baked, as acknowledged by at least some members of
the standards committee.

So once again, contrary to the position put forth in the post to which I was
responding, efficiency is not an argument against static enforcement of
exception specifications, only against runtime enforcement as required by
the C++ standard.

Anders.

--
Anders Pytte                                   Milkweed Software
PO Box 32                                  voice: (802) 586-2545
Craftsbury, VT 05826                  email: anders@milkweed.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Anders Pytte <anders@milkweed.com>
Date: 15 Sep 00 04:02:54 GMT
Raw View
in article VA.0000038b.77d43cc1@nospam.demon.co.uk, Daniel James at
internet@nospam.demon.co.uk wrote on 9/14/00 8:29 AM:

[snip]

> Andrew's example suggests to me that we need to invent a new language
feature
> to
> enable the programmer to tell the compiler that a section of code can't
really
> throw some exception even though it is mentioned throw specification of
some
> function that is called. Unfortunately this would still need some
verification
> at
> runtime in case the programmer's assertion proved to be wrong, so maybe
the
> best
> answer is simply to catch the exception that supposedly can't happen and
to
> throw
> unexpected if it does?

This would be acceptable if the compiler was only obliged to implement
unexpected handling around snips of code that turned off static checking,
otherwise you're squandering your profits. Also, I'm not sure you would be
allowed to re-throw from the unexpected handler because there is no way the
compiler could ensure that the exception thrown from the handler matched
the
exception specification.

Since the cost of "unexpected" support is about the same as a try-catch
block, you could just require the engineer to write his or her own
try-catch
block around the code in question, for the same effect, or make the
compiler
switch mean "place a try-catch block here that ignores all exceptions".

But I would prefer no checking at all - just trust the engineer. If a
function that is declared no-throw throws where the engineer turned off
static enforcement, and the failure handling for that function was
optimized
away, it could just be treated as an uncaught exception, terminating the
application.

Anders.

--
Anders Pytte                                   Milkweed Software
PO Box 32                                  voice: (802) 586-2545
Craftsbury, VT 05826                  email: anders@milkweed.com


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]




Author: Daniel James <internet@nospam.demon.co.uk>
Date: 2000/09/15
Raw View
In article <B5E6516B.C3B8%anders@milkweed.com>, Anders Pytte wrote:
> > [me] ... maybe the best answer is simply to catch the exception
> > that supposedly can't happen and to throw unexpected if it does?
>
> This would be acceptable if the compiler was only obliged to implement
> unexpected handling around snips of code that turned off static checking,
> otherwise you're squandering your profits.

Whilst I certainly do feel that any implementation that did support
compile-time checking of throw specifications almost certainly would provide
some means to turn that checking off, I was deliberately not considering that
possibility in my post.

I think that the aim should be to have code that compiles cleanly with
rigorous compile-time checking of thow specs, and then have the option to
turn off the *runtime* checks altogether. After all, there's no point in
checking code at runtime for an exception that we already know it can't throw
(which I think is the same thing as Andrew was saying, though in a rather
different context).

> Also, I'm not sure you would be allowed to re-throw from the
> unexpected handler because there is no way the compiler could
> ensure that the exception thrown from the handler matched the
> exception specification.

No, indeed, my mistake. As Andrew's code stands it can't rethrow or thow
unexpected. The compiler *can* check this - because it knows the throw spec
for the (extended implementation of) operator+ and so knows that it can throw
(as I postulated) InternalArithException - but the result will be to fail at
compile time because it knows that the exception specification doesn't
include either InternalArithException or unexcpetd. I should have said "call
the unexpected handler explicitly if it does".

It doesn't actually matter in this case because the operator+ won't throw
anyway (so long as the checks for overflow and underflow conditions are
correct). What I was trying to point out is that putting a catch block around
the arithmetic - even though we believe it can't throw - is one way to make
the code exception-correct. It's not very nice, but I think it's better than
turning off the checking.

Of course, it has no runtime ovehead at all (as long as we are correct in
believeing that sufficient checking has been carried out to ensure that
operator+ will not throw - if the programmer makes a mistake he will discover
it when the unexpected handler is called (which is certainly better than not
discovering at all).

> Since the cost of "unexpected" support is about the same as a try-catch
> block, you could just require the engineer to write his or her own
> try-catch block around the code in question, for the same effect, or
> make the compiler switch mean "place a try-catch block here that
> ignores all exceptions".

Pretty much what I was suggesting.

I also wondered about a new construct along the lines of

  try
  {
    return x + y;
  }
  ignore( InternalArithException )
  catch( ... )
  {
    ...some diagnostic...

    return 0;
  }

> But I would prefer no checking at all - just trust the engineer. If a
> function that is declared no-throw throws where the engineer turned off
> static enforcement, and the failure handling for that function was
> optimized away, it could just be treated as an uncaught exception,
> terminating the application.

If we can come up with a workable scheme whereby the exception-correctness of
code can be guaranteed at compile time - even if it means a few catch blocks
that we know will never be entered - I'd like to use it. Even so we'll have
to trust the engineer not to have turned checking off <smile>, and we'll
probably have to turn the checking off on occasions to cope with legacy code
that doesn't include throw specs.

To make this worthwhile the standard will have to be upgraded to make
exception checking across compilation units possible, and - as has already
been said - this isn't a trivial task.

Cheers,
 Daniel
[nospam.demon.co.uk is a spam-magnet. Replace nospam with sonadata to reply]
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Andrew Koenig <ark@research.att.com>
Date: 12 Sep 2000 16:21:43 -0400
Raw View
Sergey> Andrew Koenig wrote:
>> int sum(int x, int y) throw(Overflow, Underflow)
>> {
>> if (x > 0 && y > 0 && x > MAXINT - y)
>>  throw Overflow();
>>      if (x < 0 && y < 0 && x < MININT - y)
>>  throw Underflow();
>>      return x + y;
>> }

Sergey>  Hmm. IMHO this is quite useless example: in an
Sergey> extended implementation x+y can throw Overflow and/or
Sergey> Underflow without your assistance :)

It can?  How?

>> This function checks the values of x and y before adding them, so that
>> it knows that computing x + y will not overflow.

Sergey>  Generally speaking, we cannot be sure: what if a
Sergey> vendor will change its "throwing criterion"? IMHO we shouldn't
Sergey> speculate on our _current_ knowledge.

If x + y is in range (which is what the program tests), then the
standard defines the behavior, and vendors are not allowed to deviate.

--
Andrew Koenig, ark@research.att.com, http://www.research.att.com/info/ark
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James Kuyper <kuyper@wizard.net>
Date: Wed, 13 Sep 2000 00:01:28 GMT
Raw View
Anders Pytte wrote:
>
> in article 39BD6F1E.C28B5DD6@wizard.net, James Kuyper at kuyper@wizard.net
> wrote on 9/12/00 11:31 AM:
...
> > You've already said that; to clear up confusion you have to say
> > something different. I suspect that what he's asking is "What do you
> > mean by 'compile time enforcement of exception specifications'?" I
> > thought that you meant that the code of a function should be required to
> > be consistent with it's exception specification. Five other people
> > thought you meant that exception specifications for the same function
> > should be kept consistent across all of the translation units that are
> > linked together in a single program.  At this point, I'm curious to find
> > out whether or not I was right.
>
> I'm sorry for being repetitive, but I still cannot read the meaning you
> suggest from that post.
>
> Contrary to what you claim, at least in my experience, clearing up confusion
> sometimes requires saying the same thing twice ;-) I was trying to avoid a

I've never seen that strategy work. If they misunderstood the question
the first time, they're likely to misunderstand it the same way the
second time. The main effect of repetition is to provoke annoyance - "I
already answered that question; wasn't he paying attention?!".
Recommendation: only repeat yourself if you actively want to annoy the
person you're doing it to.

...
> Reviewing my original post, I agree that I could hardly have been less
> clear. I meant the meaning you took. I suspect the other readers did as
> well. Since consistency between the function's declaration and definition
> would require consistency across translation units, their responses were
> justified by the intended meaning.

No, I see now that I misunderstood your meaning, but you've evened out
the scales by misunderstanding mine. I was talking about consistency
between the exception specification in a function declaration, and the
code that makes up the body of the function. That's a very different
issue from the issue of the consistency of two different declarations of
the same function, whether or not one of those declarations is also a
definition.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James Kuyper <kuyper@wizard.net>
Date: Wed, 13 Sep 2000 00:07:10 GMT
Raw View
"Sergey P. Derevyago" wrote:
...
>         IMHO it should be done: writing of a robust and efficient code becomes
> unnecessary complex without such compile time enforcement, especially a generic
> code. The current run-time checking is much worse than old pre-ANSI C:
>
>  double f();  // "declare"
>  a=f(b, c);   // and call. Sometimes this works...

That code would compile with pre-ANSI C, and even with C89. It will
still compile with C99. It will even work correctly, so long as f() is
defined as taking two arguements with types compatible with the promoted
types of 'b' and 'c', respectively.

What is the distinction you're trying to show between "current" and
"previous" run-time checking? At least in C++ this code would be illegal
(unless there's an overrider of f() in scope that does take two
arguments of suitable types - but in that case, it's not a defect).

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Anders Pytte <anders@milkweed.com>
Date: 2000/09/13
Raw View
in article 39BEC690.D9AD281B@wizard.net, James Kuyper at kuyper@wizard.net
wrote on 9/12/00 8:01 PM:

> Anders Pytte wrote:
>>
>> Contrary to what you claim, at least in my experience, clearing up confusion
>> sometimes requires saying the same thing twice ;-) I was trying to avoid a
>
> I've never seen that strategy work. If they misunderstood the question
> the first time, they're likely to misunderstand it the same way the
> second time. The main effect of repetition is to provoke annoyance - "I
> already answered that question; wasn't he paying attention?!".
> Recommendation: only repeat yourself if you actively want to annoy the
> person you're doing it to.

I've seen it work - perhaps even in this case!

Not everyone reads as carefully the first time as you do.

Nevertheless, I'll try to take your advice.

I'm sure I'll be a better person for my efforts.

>> Reviewing my original post, I agree that I could hardly have been less
>> clear. I meant the meaning you took. I suspect the other readers did as
>> well. Since consistency between the function's declaration and definition
>> would require consistency across translation units, their responses were
>> justified by the intended meaning.
>
> No, I see now that I misunderstood your meaning, but you've evened out
> the scales by misunderstanding mine. I was talking about consistency
> between the exception specification in a function declaration, and the
> code that makes up the body of the function. That's a very different
> issue from the issue of the consistency of two different declarations of
> the same function, whether or not one of those declarations is also a
> definition.

Then we were talking about the same thing :-! By function "definition" i
meant the code, the implementation. I thought that was what the definition
was. I'll use the word implementation to be clearer, though. You might have
taken a hint from the fact that consistency between the exception
specifications (in the interface and implementation) are already statically
enforced.

For anyone who is not clear about this yet: the compiler could search the
function implementation for throw statements, and it could check all the
functions called in the function implementation for their exception
specifications, and, finding any possibility of an exception being thrown
that is not in the exception specification for the function implementation,
report an error.

The above procedure, executed over all the code for a closed system, could
ensure at compile time that all possible exceptions were correctly handled.
If this could be done, no runtime mechanism (i.e. unexpected exception
handling) would be required, and significant optimizations could be made
where there was no possibility of exceptions and associated failure handling
is not needed.

That is what I mean by "correctness between the implementation and the
interface" in what follows, and is the ultimate benefit of exception
specifications, and I think there is no reason to add more static
enforcement of exception specifications to the language unless that benefit
can be achieved.

The compiler cannot enforce correctness between the implementation and the
interface (i.e. declaration) unless it knows that the specifications for
each function called in the implementation are statically correct in the
same sense, and it cannot know those specifications are correct without
enforcing correctness across translation units.

If we reserve the ability to change an exception specification in one
translation unit without forcing recompilation of the entire system, then
correctness may only be enforced at runtime. This seemed to be Stroustrups
argument, and the same one put forth here by several others.

Hope I was finally clear, even if at the cost of some repetition.

Regards,

Anders.

--
Anders Pytte                                   Milkweed Software
PO Box 32                                  voice: (802) 586-2545
Craftsbury, VT 05826                  email: anders@milkweed.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Anders Pytte <anders@milkweed.com>
Date: 13 Sep 2000 05:29:06 -0400
Raw View
in article to9v5.82923$_s1.995808@typhoon.ne.mediaone.net, David Abrahams at
abrahams@mediaone.net wrote on 9/12/00 10:03 AM:

Hi Dave,

I could have been clearer, I suppose. I meant that, given complete compile
time enforcement, then exception specifications may provide performance
benefits. This meaning should have been evident from the preceding posts to
this thread.

However, your extremism in opposition to exception specifications has been
so well cultivated that you overlooked this possible meaning ;-)

I am aware that there are runtime costs associated with the current half-
baked implementation of exception specifications. But for statically
enforced exception specifications, there is no associated runtime cost, and
I can imagine certain optimizations that a compiler might make, if it knew
that a particular function could not throw.

Regards,

Anders.

> "Anders Pytte" <anders@milkweed.com> wrote in message
> news:B5E09C98.BFF7%anders@milkweed.com...
>
>> If anything, compile time enforcement of exception specifications provides
>> performance benefits. For one thing, you could get rid of unexpected
>> exception handling; for another, the compiler could make certain
>> optimizations where it knew a function could not throw.
>
> I'm not going to "jump up and down about this" here, lest Lois Goldthwaite
> bust my chops (and you don't want to mess with Lois), but I _am_ going to
> try to set the record straight on this.
>
> First of all, how an exception-specification affects performance is
> implementation-dependent.
>
> That said, on all implementations I know of, an exception-specification is
> implemented very much like a try catch block:
>
> void f() throw(E1, E2) { function-body }
>
> Is almost equivalent to:
>
> void f()
> {
> try {
> function body
> }
> catch(const E1&) {
> throw;
> }
> catch(const E2&) {
> throw;
> }
> catch(...) {
> call_unexpected();
> // never returns
> }
> }
>
> On many popular implementations, there is an runtime cost just to enter a
> try block. On these implementations, in general, you will pay the
> corresponding price for every exception-specification.
>
> Even on better implementations where there is no runtime cost to enter a try
> block, you pay a price in code or data size for maintaining this
> information. It has a runtime effect; the semantics have to be stored
> somewhere!
>
> There is only one case where you can achieve an optimization advantage by
> writing an exception-specification, and for that to happen, one of these
> conditions must hold in the caller of your function (slightly simplified):
>
> 1. All exception-specifications* of functions called in the body of a try or
> block or compound statement with auto variables having non-trivial
> destructors are empty
> 2. No exception-specification* of a function called in the body of a try
> block contains a type matching a catch handler for that try block.
> [3. The exception-specification of the caller contains only exceptions
> specified by functions it calls... but you might not want to consider that
> case because it is always true of the implicit throw(...) specification you
> get by default]
>
> * remember to include the implicit throw(...) specification of functions
> without exception-specifications in this.
>
> Finally, the compiler must implement the optimization. Currently, very few
> compilers do that. Most compilers of sufficient sophistication to optimize
> exception stuff at all are targeting machines with virtual memory, so they
> trade space for speed. Code and data related to throwing exceptions is not
> on the critical path, so it can be large as long as stays out of the working
> set. All of the exception-specification stuff gets stored with the catch
> blocks, increasing your program size at no runtime cost unless an exception
> is thrown.
>
> Thus, the likelihood that you'll achieve any kind of optimization with
> arbitrary application of exception-specifications on any random compiler is
> very low. If you want to take advantage of the potential optimization,
> remember to measure your results with every compiler you target, to see what
> you're getting.

--
Anders Pytte                                   Milkweed Software
PO Box 32                                  voice: (802) 586-2545
Craftsbury, VT 05826                  email: anders@milkweed.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "David Abrahams" <abrahams@mediaone.net>
Date: 14 Sep 00 02:59:13 GMT
Raw View
"Anders Pytte" <anders@milkweed.com> wrote in message
news:B5E3F849.C210%anders@milkweed.com...

> Hi Dave,

Hi, Anders <sigh>

> I could have been clearer, I suppose. I meant that, given complete compile
> time enforcement, then exception specifications may provide performance
> benefits. This meaning should have been evident from the preceding posts
to
> this thread.

Even if that were your meaning, it wouldn't really be accurate. The
potential performance benefits don't depend one whit on complete compile
time enforcement. If by "performance" you mean speed in the non-exception
case, then the potential benefits depend on a peculiar combination of
conditions that doesn't hold for _any_ compiler I know of: the compiler has
to optimize based on exception-specifications but must have an
exception-handling implementation that normally incurs runtime overhead for
entering a try block or constructing an object on the stack with a
non-trivial destructor.

> However, your extremism in opposition to exception specifications has been
> so well cultivated that you overlooked this possible meaning ;-)

I am not opposed to exception-specifications at all. I _am_ opposed to the
their uninformed use based on incorrect assumptions... but you overlooked
this possible meaning. Inaccurate perception of this language feature runs
rampant. When someone as obviously intelligent as you writes, "If anything,
compile time enforcement of exception specifications provides performance
benefits" in this newsgroup, it has an influence. If you don't want me to
correct your posts, make them accurate.

> I am aware that there are runtime costs associated with the current half-
> baked implementation of exception specifications.

That's only true of some implementations. There is always a cost in space
unless the exception-specification is optimized away.

> But for statically
> enforced exception specifications, there is no associated runtime cost,
and
> I can imagine certain optimizations that a compiler might make, if it knew
> that a particular function could not throw.

Compilers which optimize based on exception-specifications _do_ static
checking...in the optimizer. These compilers exist today, and are capable of
optimizing away the space cost of an exception-specification when the
conditions I outlined in my previous post hold... but as far as I know they
all have a "zero-runtime-overhead" implementation of exception-handling, so
there's no significant runtime cost to exception-specifications anyway.

my-wife-expects-me-to-read-her-mind-too-ly y'rs,
Dave



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]




Author: "Sergey P. Derevyago" <non-existent@iobox.com>
Date: 14 Sep 00 02:59:44 GMT
Raw View
Andrew Koenig wrote:
> Sergey> Andrew Koenig wrote:
> >> int sum(int x, int y) throw(Overflow, Underflow)
> >> {
> >>      if (x > 0 && y > 0 && x > MAXINT - y)
> >>              throw Overflow();
> >>      if (x < 0 && y < 0 && x < MININT - y)
> >>              throw Underflow();
> >>      return x + y;
> >> }
>
> Sergey>         Hmm. IMHO this is quite useless example: in an
> Sergey> extended implementation x+y can throw Overflow and/or
> Sergey> Underflow without your assistance :)
> It can?  How?

If in an extended implementation x+y throws Overflow when (x > 0 && y > 0
&& x
> MAXINT - y) is true then following snippet of code

 {
  if (x > 0 && y > 0 && x > MAXINT - y) throw Overflow();
  x+y;
 }

is logically equal to simple

 {
  x+y;
 }

IMHO it's quite obvious :)

> Sergey>         Generally speaking, we cannot be sure: what if a
> Sergey> vendor will change its "throwing criterion"? IMHO we shouldn't
> Sergey> speculate on our _current_ knowledge.
> If x + y is in range (which is what the program tests), then the
> standard defines the behavior, and vendors are not allowed to deviate.

 Thus this code

int sum(int x, int y) throw(Overflow, Underflow)
{
      if (x > 0 && y > 0 && x > MAXINT - y)
              throw Overflow();
      if (x < 0 && y < 0 && x < MININT - y)
              throw Underflow();
      return x + y;
}

makes integer addition portable? Hmm. IMHO machine-dependent implementation
(i.e. in terms of hardware interrupts) would be much more practical.
--
         With all respect, Sergey.          http://cpp3.virtualave.net/
         mailto : ders at skeptik.net

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]




Author: Daniel James <internet@nospam.demon.co.uk>
Date: 2000/09/14
Raw View
In article <39BC9E3D.7563CD3C@iobox.com>, Sergey P. Derevyago wrote:
> >         int sum(int x, int y) throw(Overflow, Underflow)
> >         {
> >                 if (x > 0 && y > 0 && x > MAXINT - y)
> >                         throw Overflow();
> >                 if (x < 0 && y < 0 && x < MININT - y)
> >                         throw Underflow();
> >                 return x + y;
> >         }
> >
>  Hmm. IMHO this is quite useless example: in an extended implementation x+y can
> throw Overflow and/or Underflow without your assistance :)
>

You're missing Andrew's point. In the hypothetical extended implementation
operator+(int,int) might throw (say) InternalArithException if the result of the
addition overflows. The function in Andrew's example would fail the compile-time
check for exception consistency because InternalArithException is not included in
the throw list, even though the programmer knows that the addition in this
function will not throw an InternalArithException becaue the test for overflow
and underflow have already ruled out any possibility of an exception from
operator+.

I have to agree that this is an interesting example of why compile-time checking
of exception specifications is a difficult thing to get right - but I do think
that compile-time checking of exception specifications would be a useful tool,
and I'd like to see it added to the standard somehow (after sober and mature
consideration, of course).

Andrew's example suggests to me that we need to invent a new language feature to
enable the programmer to tell the compiler that a section of code can't really
throw some exception even though it is mentioned throw specification of some
function that is called. Unfortunately this would still need some verification at
runtime in case the programmer's assertion proved to be wrong, so maybe the best
answer is simply to catch the exception that supposedly can't happen and to throw
unexpected if it does?

Cheers,
 Daniel
[nospam.demon.co.uk is a spam-magnet. Replace nospam with sonadata to reply]
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Tim McCarthy" <tfmccarthy@erols.com>
Date: 2000/09/14
Raw View
Andrew Koenig <ark@research.att.com> wrote in message
news:yu997l8monju.fsf@europa.research.att.com...
<snip Q: Why no compile time enforcement of exception specifications>

> One reason is that doing so would have made it impossible for vendors
> to extend their implementations to make arithmetic overflows throw
> exceptions.
>
> For example:
>
> int sum(int x, int y) throw(Overflow, Underflow)
> {
> if (x > 0 && y > 0 && x > MAXINT - y)
> throw Overflow();
> if (x < 0 && y < 0 && x < MININT - y)
> throw Underflow();
> return x + y;
> }
>
> This function checks the values of x and y before adding them, so that
> it knows that computing x + y will not overflow.  However, if the
> implementation throws an exception on overflow, static checking
> will reject this program because x + y might throw an exception
> that the programmer (but not the compiler) knows can never occur.

I guess I don't get the question since this didn't add up to me. Why would
the compiler reject the program for overflow? It's one of the exceptions
that sum specifies it throws.

I thought one idea was to have the compiler guarantee that any exception
specifications defined by an interface would be handled i.e. by the calling
code. The above code specifies that sum may throw 2 exceptions, which it
explicitly does. The compiler could check to insure that all the specified
exceptions are handled in the code that uses sum.

Conversely, since it's not required for interfaces to specify exceptions in
order to throw them nor is it necessary for a compiler to see the
implementation to use it, the compiler can't insure that sum doesn't let
unspecified exceptions escape. If the implementation of x + y throws an
exception other than [Overflow, Underflow] then it should/must be handled by
sum or converted to an "unexpected" exception and passed to the calling
code. OTOH, if you have all the source then the compiler could warn about
"mismatched" exception specifications for sum or flag unspecified exceptions
in code called by sum.

All this seems to lead towards limiting the exceptions; the aim being to
insure that all exceptions are handled by a single unspecified handler or by
explicit handlers that match the exceptions specifications in the code.

--
Tim McCarthy
tfmccarthy@erols.com



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James Kuyper <kuyper@wizard.net>
Date: 2000/09/14
Raw View
Anders Pytte wrote:
>
> in article 39BEC690.D9AD281B@wizard.net, James Kuyper at kuyper@wizard.net
> wrote on 9/12/00 8:01 PM:
>
> > Anders Pytte wrote:
...
> > No, I see now that I misunderstood your meaning, but you've evened out
> > the scales by misunderstanding mine. I was talking about consistency
> > between the exception specification in a function declaration, and the
> > code that makes up the body of the function. That's a very different
> > issue from the issue of the consistency of two different declarations of
> > the same function, whether or not one of those declarations is also a
> > definition.
>
> Then we were talking about the same thing :-! By function "definition" i
> meant the code, the implementation. I thought that was what the definition
> was. I'll use the word implementation to be clearer, though. You might have

A definition includes the body of the function, but it also includes the
declaration that precedes the body. When you talk about a declaration
matching a definition, that can be interpreted as referring to the
declaration portion of the definition being compatible with the other
declaration. That's how I mis-interpreted your earlier comment:

| ... Since consistency between the function's declaration and
definition
| would require consistency across translation units, their responses
were
| justified by the intended meaning.

Now that I understand what you meant, I see that "require" and
"justified" clearly covers the difference between the two concepts. I
didn't notice that at the time.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Andrew Koenig <ark@research.att.com>
Date: 2000/09/14
Raw View
Sergey> If in an extended implementation x+y throws Overflow when
Sergey>  (x > 0 && y > 0 && x > MAXINT - y) is true then
Sergey>  following snippet of code

Sergey>  {
Sergey>   if (x > 0 && y > 0 && x > MAXINT - y) throw Overflow();
Sergey>   x+y;
Sergey>  }

Sergey> is logically equal to simple

Sergey>  {
Sergey>   x+y;
Sergey>  }

Sergey> IMHO it's quite obvious :)

It is far from obvious.  An implementation is permitted to throw
Overflow on integer overflow, but it is not obliged to do so.
Therefore, if I want to write a program that reliably throws Overflow
or Underflow on every implementation, I must do the testing myself.

If I do so, it is unreasonable to assume that any implementation will
be clever enough to figure out what I'm doing and generate identical
code for the two examples above.

Sergey> Generally speaking, we cannot be sure: what if a vendor will
Sergey> change its "throwing criterion"? IMHO we shouldn't speculate
Sergey> on our _current_ knowledge.

Exactly.

>> If x + y is in range (which is what the program tests), then the
>> standard defines the behavior, and vendors are not allowed to deviate.

Sergey>  Thus this code

Sergey> int sum(int x, int y) throw(Overflow, Underflow)
Sergey> {
Sergey>       if (x > 0 && y > 0 && x > MAXINT - y)
Sergey>               throw Overflow();
Sergey>       if (x < 0 && y < 0 && x < MININT - y)
Sergey>               throw Underflow();
Sergey>       return x + y;
Sergey> }

Sergey> makes integer addition portable?

Yes, that is its purpose.

Sergey> Hmm. IMHO machine-dependent implementation (i.e. in terms of
Sergey> hardware interrupts) would be much more practical.

I think it is more practical to write programs that will work under
any standard-conforming implementation than it is to expect every
implementation to change to suit the programs I would like to write.

--
Andrew Koenig, ark@research.att.com, http://www.research.att.com/info/ark
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Anders Pytte <anders@milkweed.com>
Date: 2000/09/14
Raw View
in article OiLv5.86222$_s1.1061158@typhoon.ne.mediaone.net, David Abrahams
at abrahams@mediaone.net wrote on 9/13/00 10:59 PM:

> "Anders Pytte" <anders@milkweed.com> wrote in message
> news:B5E3F849.C210%anders@milkweed.com...
>
>> Hi Dave,
>
> Hi, Anders <sigh>
>
>> I could have been clearer, I suppose. I meant that, given complete compile
>> time enforcement, then exception specifications may provide performance
>> benefits. This meaning should have been evident from the preceding posts
> to
>> this thread.
>
> Even if that were your meaning, it wouldn't really be accurate. The
> potential performance benefits don't depend one whit on complete compile
> time enforcement.

You were right about this. I was wrong.

Exception specifications have no runtime cost when statically enforced,
making them more efficient than exception specifications that are enforced
at runtime. That was the main thrust of the post which you originally
disputed.

However, as you say, the same code optimizations, described below, are
available where runtime enforcement is used, because the exception
specification still guarantees that an exception not in the list cannot
"escape" the function.

> There is only one case where you can achieve an optimization advantage by
> writing an exception-specification, and for that to happen, one of these
> conditions must hold in the caller of your function (slightly simplified):
>
> 1. All exception-specifications* of functions called in the body of a try or
> block or compound statement with auto variables having non-trivial
> destructors are empty
> 2. No exception-specification* of a function called in the body of a try
> block contains a type matching a catch handler for that try block.
> [3. The exception-specification of the caller contains only exceptions
> specified by functions it calls... but you might not want to consider that
> case because it is always true of the implicit throw(...) specification you
> get by default]
>
> * remember to include the implicit throw(...) specification of functions
> without exception-specifications in this.

I'm having a little trouble parsing what you wrote, but I think I can
summarize as follows:

The compiler is able to determine which exceptions are possible within any
specific try block, and so, in the cases where no exceptions are possible,
or where the possible exceptions are not handled by the catch statements
associated with that try block, that try-catch could be omitted by the
compiler.

The use of exception specifications can increase the likely hood that the
compiler can make the above optimization. However, compilers may not bother
making the optimization, the improvement in efficiency may not be
significant, and the above conditions may not occur frequently enough to
make the optimization meaningful.

In any case - and I need to emphasize this - the main benefits of exception
specifications are not related to efficiency, but to system correctness. I
have never claimed otherwise.

One cannot argue against exception specifications in general by claiming
that they have runtime costs. That was the position of the post which
started this exchange. This argument only comes up in relationship to the
current half-baked C++ implementation of exception specifications.

Anders.


--
Anders Pytte                                   Milkweed Software
PO Box 32                                  voice: (802) 586-2545
Craftsbury, VT 05826                  email: anders@milkweed.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Anders Pytte <anders@milkweed.com>
Date: 2000/09/14
Raw View
in article OiLv5.86222$_s1.1061158@typhoon.ne.mediaone.net, David Abrahams
at abrahams@mediaone.net wrote on 9/13/00 10:59 PM:

> "Anders Pytte" <anders@milkweed.com> wrote in message
> news:B5E3F849.C210%anders@milkweed.com...
>
>> Hi Dave,
>
> Hi, Anders <sigh>
>
>> I could have been clearer, I suppose. I meant that, given complete compile
>> time enforcement, then exception specifications may provide performance
>> benefits. This meaning should have been evident from the preceding posts
> to
>> this thread.
>
> Even if that were your meaning, it wouldn't really be accurate. The
> potential performance benefits don't depend one whit on complete compile
> time enforcement.

Oops, I'm sorry, Dave is correct about this. Moderator - you have my
permission to remove my previous post disputing what Dave writes here.

However, I want to note, for clarity sake, that I was responding to a poster
who suggested that there was a performance cost to statically enforced
exception specifications. There is not.

Anders.

--
Anders Pytte                                   Milkweed Software
PO Box 32                                  voice: (802) 586-2545
Craftsbury, VT 05826                  email: anders@milkweed.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Anders Pytte <anders@milkweed.com>
Date: 2000/09/14
Raw View
in article OiLv5.86222$_s1.1061158@typhoon.ne.mediaone.net, David Abrahams
at abrahams@mediaone.net wrote on 9/13/00 10:59 PM:

> "Anders Pytte" <anders@milkweed.com> wrote in message
> news:B5E3F849.C210%anders@milkweed.com...
>
>> Hi Dave,
>
> Hi, Anders <sigh>
>
>> I could have been clearer, I suppose. I meant that, given complete compile
>> time enforcement, then exception specifications may provide performance
>> benefits. This meaning should have been evident from the preceding posts
> to
>> this thread.
>
> Even if that were your meaning, it wouldn't really be accurate. The
> potential performance benefits don't depend one whit on complete compile
> time enforcement. If by "performance" you mean speed in the non-exception
> case, then the potential benefits depend on a peculiar combination of
> conditions that doesn't hold for _any_ compiler I know of: the compiler has
> to optimize based on exception-specifications but must have an
> exception-handling implementation that normally incurs runtime overhead for
> entering a try block or constructing an object on the stack with a
> non-trivial destructor.

I think we're getting lost here. My original statement, which you seemed to
dispute, read:

"If anything, compile time enforcement of exception specifications provides
performance benefits".

I was responding to a post which seemed to claim that static enforcement
would incur a performance costs. In that context, what I wrote seems
reasonable. However, in light of your offense, I might have said:

"Compared to runtime enforcement, static enforcement of exception
specifications provides either space or performance benefits; in fact,
statically enforced exception specifications have no runtime cost;
furthermore, use of exception specifications, where statically enforced, may
provide some runtime benefits."

Does that seem more accurate to you? Nowhere have I claim the benefits of
using exception specifications were guaranteed or that the benefits would be
significant.

....

In your latest post, your wrote:

> There is only one case where you can achieve an optimization advantage by
> writing an exception-specification, and for that to happen, one of these
> conditions must hold in the caller of your function (slightly simplified):
>
> 1. All exception-specifications* of functions called in the body of a try or
> block or compound statement with auto variables having non-trivial
> destructors are empty
> 2. No exception-specification* of a function called in the body of a try
> block contains a type matching a catch handler for that try block.
> [3. The exception-specification of the caller contains only exceptions
> specified by functions it calls... but you might not want to consider that
> case because it is always true of the implicit throw(...) specification you
> get by default]
>
> * remember to include the implicit throw(...) specification of functions
> without exception-specifications in this.

I'm having a little trouble parsing what you wrote, but I think I can
summarize as follows:

If exception specifications were statically enforced, the compiler would be
able to determine which exceptions were possible within any specific try
block, and so, in the cases where no exceptions are possible, or where the
possible exceptions are not handled by the catch statements associated with
that try block, that try-catch could be omitted by the compiler.

I am not saying that this condition would arise frequently, okay? It is hard
to know whether any compiler writer would implement this optimization, if
static enforcement of exception specifications were required by the
standard. But it is unreasonable to assume they would not.

In any case - and I need to emphasize this - the main benefits of exception
specifications are not related to efficiency, but to system correctness. I
have never claimed otherwise.

One cannot argue against exception specifications in general by claiming
they have runtime costs. That was the position of the post which started
this exchange. This argument only comes up in relationship to the current
half-baked C++ implementation of exception specifications.

Statically enforced exception specifications have no associated runtime
costs; "if anything", they have runtime benefits.

Anders.


--
Anders Pytte                                   Milkweed Software
PO Box 32                                  voice: (802) 586-2545
Craftsbury, VT 05826                  email: anders@milkweed.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Andrew Koenig <ark@research.att.com>
Date: 2000/09/14
Raw View
>> One reason is that doing so would have made it impossible for vendors
>> to extend their implementations to make arithmetic overflows throw
>> exceptions.

>> For example:

>> int sum(int x, int y) throw(Overflow, Underflow)
>> {
>> if (x > 0 && y > 0 && x > MAXINT - y)
>> throw Overflow();
>> if (x < 0 && y < 0 && x < MININT - y)
>> throw Underflow();
>> return x + y;
>> }

>> This function checks the values of x and y before adding them, so that
>> it knows that computing x + y will not overflow.  However, if the
>> implementation throws an exception on overflow, static checking
>> will reject this program because x + y might throw an exception
>> that the programmer (but not the compiler) knows can never occur.

Tim> I guess I don't get the question since this didn't add up to me. Why would
Tim> the compiler reject the program for overflow? It's one of the exceptions
Tim> that sum specifies it throws.

The point is that if x+y overflows, the behavior is undefined.
That means that the compiler is permitted to do absolutely anything
at all, including throwing absolutely any exception at all.

Now, suppose I want to compile this program on a compiler that
happens to throw Arithmetic_error if integer addition overflows.
Under static checking, wouldn't the compiler be justified in
rejecting the program because it doesn't include Arithmetic_error
in the list of exceptions that it might throw?

The trouble is that as the author of the function, I know that it
can't possibly throw such an exception, because I have checked
the values of x and y beforehand.  Shouldn't I feel justified
in writing such a program?  Or should I have to write

 int sum(int x, int y) throw(Overflow, Underflow)
 {
     if (x > 0 && y > 0 && x > MAXINT - y)
         throw Overflow();
     if (x < 0 && y < 0 && x < MININT - y)
         throw Underflow();
     try {
         return x + y;
     } catch(...) {
  // This cannot happen
  return 0;
     }
 }

just so that I do not run afoul of a static check for a condition
that I know can never happen?



--
Andrew Koenig, ark@research.att.com, http://www.research.att.com/info/ark
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Anders Pytte <anders@milkweed.com>
Date: 08 Sep 00 14:08:03 GMT
Raw View
Folks,

Sorry to dig this up again. But when a colleague asked me, I could not
remember the reason(s) why the standard committee chose not to include
compile time enforcement of exception specifications.

Please no speculation; a definitive answer desired.

Thanks,

Anders.


--
Anders Pytte                                   Milkweed Software
PO Box 32                                  voice: (802) 586-2545
Craftsbury, VT 05826                  email: anders@milkweed.com


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]




Author: "Sergey P. Derevyago" <non-existent@iobox.com>
Date: 12 Sep 00 08:06:10 GMT
Raw View
wmm@fastdial.net wrote:
> The feeling was that the current non-type nature of
> exception specifications allowed a number of useful,
> albeit non-exhaustive, compile-time checks and so was
> good enough considering the cost of the alternative.  The
> suggestion that exception specifications be part of the
> function type is raised occasionally -- there's an open
> issue on the core language issues list to that effect --
> but there's no currently-active movement in that direction.
 IMHO it should be done: writing of a robust and efficient code becomes
unnecessary complex without such compile time enforcement, especially a generic
code. The current run-time checking is much worse than old pre-ANSI C:

 double f();  // "declare"
 a=f(b, c);   // and call. Sometimes this works...

--
         With all respect, Sergey.          http://cpp3.virtualave.net/
         mailto : ders at skeptik.net

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]




Author: "Sergey P. Derevyago" <non-existent@iobox.com>
Date: 12 Sep 00 08:07:05 GMT
Raw View
Andrew Koenig wrote:
>
> Anders> Folks,
> Anders> Sorry to dig this up again. But when a colleague asked me, I could not
> Anders> remember the reason(s) why the standard committee chose not to include
> Anders> compile time enforcement of exception specifications.
>
> Anders> Please no speculation; a definitive answer desired.
>
> One reason is that doing so would have made it impossible for vendors
> to extend their implementations to make arithmetic overflows throw
> exceptions.
>
> For example:
>
>         int sum(int x, int y) throw(Overflow, Underflow)
>         {
>                 if (x > 0 && y > 0 && x > MAXINT - y)
>                         throw Overflow();
>                 if (x < 0 && y < 0 && x < MININT - y)
>                         throw Underflow();
>                 return x + y;
>         }
>
 Hmm. IMHO this is quite useless example: in an extended implementation x+y can
throw Overflow and/or Underflow without your assistance :)

> This function checks the values of x and y before adding them, so that
> it knows that computing x + y will not overflow.
 Generally speaking, we cannot be sure: what if a vendor will change its
"throwing criterion"? IMHO we shouldn't speculate on our _current_ knowledge.

> However, if the
> implementation throws an exception on overflow, static checking
> will reject this program because x + y might throw an exception
> that the programmer (but not the compiler) knows can never occur.
 errare est humanum, errare humanum est
--
         With all respect, Sergey.          http://cpp3.virtualave.net/
         mailto : ders at skeptik.net

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]




Author: James Kuyper <kuyper@wizard.net>
Date: Tue, 12 Sep 2000 15:31:54 GMT
Raw View
Anders Pytte wrote:
>
> in article 8pbbn6$o5b$1@news6.svr.pol.co.uk, Martin Aspeli at
> anakin24@bigfoot.com wrote on 9/10/00 1:13 AM:
>
> >> Sorry to dig this up again. But when a colleague asked me, I could not
> >> remember the reason(s) why the standard committee chose not to include
> >> compile time enforcement of exception specifications.
> >
> > I'm not sure I understand exactly what you mean, but according to
> > www.ootips.org, some people beleive that exception specifications are bad
> > because they produce a dependency between the caller and the class itself.
>
> I was asking specifically for the reasoning used by the committee to reject
> compile time enforcement of exception specifications. I can think of
> possible reasons myself, but I'm not the committee.

You've already said that; to clear up confusion you have to say
something different. I suspect that what he's asking is "What do you
mean by 'compile time enforcement of exception specifications'?" I
thought that you meant that the code of a function should be required to
be consistent with it's exception specification. Five other people
thought you meant that exception specifications for the same function
should be kept consistent across all of the translation units that are
linked together in a single program.  At this point, I'm curious to find
out whether or not I was right.

I'm posting this twice, once to comp.lang.C++.moderated and once to
comp.std.c++. Sorry - but my newsserver won't let me cross-post to two
different moderated newsgroups, and I'm not sure which of the two you
actually monitor. I only monitor comp.std.c++. I've set followups to go
to
both groups.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "David Abrahams" <abrahams@mediaone.net>
Date: 12 Sep 00 14:03:54 GMT
Raw View
"Anders Pytte" <anders@milkweed.com> wrote in message
news:B5E09C98.BFF7%anders@milkweed.com...

> If anything, compile time enforcement of exception specifications provides
> performance benefits. For one thing, you could get rid of unexpected
> exception handling; for another, the compiler could make certain
> optimizations where it knew a function could not throw.

I'm not going to "jump up and down about this" here, lest Lois Goldthwaite
bust my chops (and you don't want to mess with Lois), but I _am_ going to
try to set the record straight on this.

First of all, how an exception-specification affects performance is
implementation-dependent.

That said, on all implementations I know of, an exception-specification is
implemented very much like a try catch block:

    void f() throw(E1, E2) { function-body }

Is almost equivalent to:

void f()
{
    try {
      function body
    }
    catch(const E1&) {
        throw;
    }
    catch(const E2&) {
        throw;
    }
    catch(...) {
        call_unexpected();
        // never returns
    }
}

On many popular implementations, there is an runtime cost just to enter a
try block. On these implementations, in general, you will pay the
corresponding price for every exception-specification.

Even on better implementations where there is no runtime cost to enter a try
block, you pay a price in code or data size for maintaining this
information. It has a runtime effect; the semantics have to be stored
somewhere!

There is only one case where you can achieve an optimization advantage by
writing an exception-specification, and for that to happen, one of these
conditions must hold in the caller of your function (slightly simplified):

1. All exception-specifications* of functions called in the body of a try or
block or compound statement with auto variables having non-trivial
destructors are empty
2. No exception-specification* of a function called in the body of a try
block contains a type matching a catch handler for that try block.
[3. The exception-specification of the caller contains only exceptions
specified by functions it calls... but you might not want to consider that
case because it is always true of the implicit throw(...) specification you
get by default]

* remember to include the implicit throw(...) specification of functions
without exception-specifications in this.

Finally, the compiler must implement the optimization. Currently, very few
compilers do that. Most compilers of sufficient sophistication to optimize
exception stuff at all are targeting machines with virtual memory, so they
trade space for speed. Code and data related to throwing exceptions is not
on the critical path, so it can be large as long as stays out of the working
set. All of the exception-specification stuff gets stored with the catch
blocks, increasing your program size at no runtime cost unless an exception
is thrown.

Thus, the likelihood that you'll achieve any kind of optimization with
arbitrary application of exception-specifications on any random compiler is
very low. If you want to take advantage of the potential optimization,
remember to measure your results with every compiler you target, to see what
you're getting.

-Dave



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]




Author: Erik Max Francis <max@alcyone.com>
Date: 12 Sep 2000 13:18:08 -0400
Raw View
"Sergey P. Derevyago" wrote:

>         IMHO it should be done: writing of a robust and efficient code
> becomes
> unnecessary complex without such compile time enforcement, especially
> a generic
> code. The current run-time checking is much worse than old pre-ANSI C:
>
>  double f();  // "declare"
>  a=f(b, c);   // and call. Sometimes this works...

Actually, that's perfectly fine ANSI C (provided, of course that f
actually _does_ take two arguments of the appropriate type; otherwise it
results in undefined behavior).  An empty parameter list in C doesn't
mean no arguments (as it does in C++), but rather puts no restrictions
on those arguments.

--
 Erik Max Francis / max@alcyone.com / http://www.alcyone.com/max/
 __ San Jose, CA, US / 37 20 N 121 53 W / ICQ16063900 / &tSftDotIotE
/  \ The most exhausting thing in life is being insincere.
\__/ Anne Morrow Lindbergh
    blackgirl international / http://www.blackgirl.org/
 The Internet resource for black women.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Anders Pytte <anders@milkweed.com>
Date: Tue, 12 Sep 2000 20:01:34 GMT
Raw View
in article 39BD6F1E.C28B5DD6@wizard.net, James Kuyper at kuyper@wizard.net
wrote on 9/12/00 11:31 AM:

> Anders Pytte wrote:
>>
>> in article 8pbbn6$o5b$1@news6.svr.pol.co.uk, Martin Aspeli at
>> anakin24@bigfoot.com wrote on 9/10/00 1:13 AM:
>>
>>>> Sorry to dig this up again. But when a colleague asked me, I could not
>>>> remember the reason(s) why the standard committee chose not to include
>>>> compile time enforcement of exception specifications.
>>>
>>> I'm not sure I understand exactly what you mean, but according to
>>> www.ootips.org, some people beleive that exception specifications are bad
>>> because they produce a dependency between the caller and the class itself.
>>
>> I was asking specifically for the reasoning used by the committee to reject
>> compile time enforcement of exception specifications. I can think of
>> possible reasons myself, but I'm not the committee.
>
> You've already said that; to clear up confusion you have to say
> something different. I suspect that what he's asking is "What do you
> mean by 'compile time enforcement of exception specifications'?" I
> thought that you meant that the code of a function should be required to
> be consistent with it's exception specification. Five other people
> thought you meant that exception specifications for the same function
> should be kept consistent across all of the translation units that are
> linked together in a single program.  At this point, I'm curious to find
> out whether or not I was right.

I'm sorry for being repetitive, but I still cannot read the meaning you
suggest from that post.

Contrary to what you claim, at least in my experience, clearing up confusion
sometimes requires saying the same thing twice ;-) I was trying to avoid a
full blown argument about this issue since we barely got done with it
recently. Seems like I failed, given my recent exchange with Dave Abrahams.

Reviewing my original post, I agree that I could hardly have been less
clear. I meant the meaning you took. I suspect the other readers did as
well. Since consistency between the function's declaration and definition
would require consistency across translation units, their responses were
justified by the intended meaning.

I thankfully read all the references suggested by the various posters. I did
not find any suggestion that the desire to make exception specifications
consistent across translation units was separate from the desire to make the
function declaration consistent with the function definition. Especially
helpful was Stroustrup D&E [16.9], where the need for separate compilation
and linkage was the only justification given for not providing static
(compile time) enforcement of consistency of the function declaration and
definition.

Regards,

Anders.


--
Anders Pytte                                   Milkweed Software
PO Box 32                                  voice: (802) 586-2545
Craftsbury, VT 05826                  email: anders@milkweed.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Andrew Koenig <ark@research.att.com>
Date: 12 Sep 2000 16:21:20 -0400
Raw View
Sergey>  IMHO it should be done: writing of a robust and
Sergey> efficient code becomes unnecessary complex without such
Sergey> compile time enforcement, especially a generic code. The
Sergey> current run-time checking is much worse than old pre-ANSI C:

Sergey>  double f();  // "declare"
Sergey>  a=f(b, c);   // and call. Sometimes this works...

In what language?  Surely not in standard C++!

--
Andrew Koenig, ark@research.att.com, http://www.research.att.com/info/ark
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Martin Aspeli" <anakin24@bigfoot.com>
Date: 10 Sep 00 05:13:09 GMT
Raw View
> Sorry to dig this up again. But when a colleague asked me, I could not
> remember the reason(s) why the standard committee chose not to include
> compile time enforcement of exception specifications.

I'm not sure I understand exactly what you mean, but according to
www.ootips.org, some people beleive that exception specifications are bad
because they produce a dependency between the caller and the class itself.

Also, no exception specification means "all exceptions can be thrown", and
in my view at least, there *should* be a way of doing so.

I'd also imagine that exception specifications introduce a (small)
performance hit, but I'm far from sure about this.

Hope that helps,
Martin



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]




Author: Andrew Koenig <ark@research.att.com>
Date: 10 Sep 2000 11:12:02 -0400
Raw View
Anders> Folks,
Anders> Sorry to dig this up again. But when a colleague asked me, I could not
Anders> remember the reason(s) why the standard committee chose not to include
Anders> compile time enforcement of exception specifications.

Anders> Please no speculation; a definitive answer desired.

One reason is that doing so would have made it impossible for vendors
to extend their implementations to make arithmetic overflows throw
exceptions.

For example:

 int sum(int x, int y) throw(Overflow, Underflow)
 {
  if (x > 0 && y > 0 && x > MAXINT - y)
   throw Overflow();
  if (x < 0 && y < 0 && x < MININT - y)
   throw Underflow();
  return x + y;
 }

This function checks the values of x and y before adding them, so that
it knows that computing x + y will not overflow.  However, if the
implementation throws an exception on overflow, static checking
will reject this program because x + y might throw an exception
that the programmer (but not the compiler) knows can never occur.



--
Andrew Koenig, ark@research.att.com, http://www.research.att.com/info/ark
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: juergen@monocerus.n-online.de (Juergen Heinzl)
Date: 10 Sep 2000 11:12:36 -0400
Raw View
In article <B5D8AE2A.B276%anders@milkweed.com>, Anders Pytte wrote:
>Folks,
>
>Sorry to dig this up again. But when a colleague asked me, I could not
>remember the reason(s) why the standard committee chose not to include
>compile time enforcement of exception specifications.
[-]
See "The C++ Programming Language", 14.6.1.

Cheers,
Juergen

--
\ Real name     : J   rgen Heinzl         \       no flames      /
 \ EMail Private : monocerus@n-online.de \ send money instead /
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Sean Kelly" <kensai@bellatlantic.net>
Date: 10 Sep 2000 11:13:36 -0400
Raw View
"Anders Pytte" <anders@milkweed.com> wrote in message
news:B5D8AE2A.B276%anders@milkweed.com...
>
> Sorry to dig this up again. But when a colleague asked me, I could not
> remember the reason(s) why the standard committee chose not to include
> compile time enforcement of exception specifications.
>
> Please no speculation; a definitive answer desired.

I'm going to reply with speculation :P  Since exception specifications could
not be required because of backwards compatibility, they could not be
enforced at compile-time -- a function might call 5 other functions, all of
which throw exceptions and only half of which use exceptions specifications.
What do you do?  Trace through the functions without specifications and look
for "throw" clauses?  This seems computationally prohibitive.

Sean
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: wmm@fastdial.net
Date: 10 Sep 2000 11:15:51 -0400
Raw View
In article <B5D8AE2A.B276%anders@milkweed.com>,
  Anders Pytte <anders@milkweed.com> wrote:
> Sorry to dig this up again. But when a colleague asked me, I could not
> remember the reason(s) why the standard committee chose not to include
> compile time enforcement of exception specifications.

There is compile-time enforcement of exception specifications,
up to a point.  You can't, for instance, weaken an exception
specification in a function pointer assignment or virtual
override (15.4p3).

Part of the answer for why thorough enforcement at compile
time isn't required is implicit in the last sentence of
15.4p3: "A diagnostic is required only if the sets of
type-ids are different within a single translation unit."
The Committee did not want to mandate checks across
separately-compiled translation units, which might be
difficult to implement or computationally expensive in
some environments.

The other reason for omitting the compile-time check was
the fact that exception specifications are not part of
the type, which means that they can't be used in typedefs,
etc.  The reason for that decision was a reluctance to
complicate the already-complex type system -- if the types
of functions with different exception specifications were
different, could you use that fact to overload them, for
instance?

The feeling was that the current non-type nature of
exception specifications allowed a number of useful,
albeit non-exhaustive, compile-time checks and so was
good enough considering the cost of the alternative.  The
suggestion that exception specifications be part of the
function type is raised occasionally -- there's an open
issue on the core language issues list to that effect --
but there's no currently-active movement in that direction.

--
William M. Miller, wmm@fastdial.net
Vignette Corporation (www.vignette.com)


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James Kuyper <kuyper@wizard.net>
Date: Sun, 10 Sep 2000 19:38:54 GMT
Raw View
Martin Aspeli wrote:
>
> > Sorry to dig this up again. But when a colleague asked me, I could not
> > remember the reason(s) why the standard committee chose not to include
> > compile time enforcement of exception specifications.

The C++ standard has no rules that require rejection of code for any
reason. It does require that any code that contains a violation of a
diagnosable rule must produce a diagnostic, but it doesn't distinguish
between diagnosing it at compile time or at run time. It's been argued,
in effect, that if a rule can be diagnosed during translation, then the
diagnostic cannot be deferred until execution of the code. However, I've
never seen a coherent argument for that claim.

Therefore, compile-time enforcement of any of the standard's rules is
purely a QoI issue. Since I was not involved in the committee's
deliberations, I can't address the OP's questions as to why that is the
case.

> I'm not sure I understand exactly what you mean, but according to

The standard currently states in 15.4p9: "An implementation shall not
reject an expression merely because when executed it throws or might
throw an exception that the containing function does not allow."

Instead of rejecting such an expression, the standard requires that if
such an object is thrown, std::unexpected() is called. By default,
std::unexpected() simply calls std::terminate(), but an alternative
function that never returns may be registered by a call to
std::set_unexpected(). If the alternative function throws an exception
not allowed by the exception specification, std::terminate() is called
anyway. By default, std::terminate() simply calls std::abort(), but an
alternative function that ends the program without returning may be
registered by a call to std::set_terminate().

I believe that the OP would like to know why this rule wasn't simply
reversed, mandating rejection rather than prohibiting it. Again, since I
wasn't in on the discussions, I can't answer that question. However, I
don't think a simple reversal of 15.4p9 would be appropriate, because
that would make it the only part of the standard requiring rejection of
code. However, what could be done is to change the reversal of 15.4p9
into a diagnosable rule, requiring a diagnostic:

"A function may not contain any expression which when executed throws or
might throw an uncaught exception that it's exception specification does
not allow."

...
> Also, no exception specification means "all exceptions can be thrown", and
> in my view at least, there *should* be a way of doing so.

There is - 15.4p11 "A function with no exception specification allows
all exceptions. ..."

> I'd also imagine that exception specifications introduce a (small)
> performance hit, but I'm far from sure about this.

The cost of an exception specification varies considerably from one
implementation to another. I've heard claims that on some
implementations the costs can be significant, but I don't know the
details.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: llewelly.@@edevnull.dot.com
Date: 10 Sep 2000 16:59:08 -0400
Raw View
Anders Pytte <anders@milkweed.com> writes:

> Folks,
>
> Sorry to dig this up again. But when a colleague asked me, I could not
> remember the reason(s) why the standard committee chose not to include
> compile time enforcement of exception specifications.
>
> Please no speculation; a definitive answer desired.

There some discoussing on this in D&E  16.9 (pgs 395-397 in my copy).



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James Kuyper <kuyper@wizard.net>
Date: Sun, 10 Sep 2000 21:29:30 CST
Raw View
Sean Kelly wrote:
>
> "Anders Pytte" <anders@milkweed.com> wrote in message
> news:B5D8AE2A.B276%anders@milkweed.com...
> >
> > Sorry to dig this up again. But when a colleague asked me, I could not
> > remember the reason(s) why the standard committee chose not to include
> > compile time enforcement of exception specifications.
> >
> > Please no speculation; a definitive answer desired.
>
> I'm going to reply with speculation :P  Since exception specifications could
> not be required because of backwards compatibility, they could not be
> enforced at compile-time -- a function might call 5 other functions, all of
> which throw exceptions and only half of which use exceptions specifications.
> What do you do?  Trace through the functions without specifications and look
> for "throw" clauses?  This seems computationally prohibitive.

The compiler should use their (missing) throw specifications. A function
without a throw clause can throw any exception. Therefore, those calls
should be treated as being able to throw anything. Therefore, if the
standard were to require compile-time enforcement, then if the calling
function has a non-default throw specification, it would be required to
wrap those function calls in a try block with at least one handler that
has catch(...). It would have been possible to require this, but very
inconvenient.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Mon, 11 Sep 2000 12:27:22 GMT
Raw View
In article <39BBB6F0.11975E48@wizard.net>, James Kuyper
<kuyper@wizard.net> writes
>The compiler should use their (missing) throw specifications. A function
>without a throw clause can throw any exception. Therefore, those calls
>should be treated as being able to throw anything. Therefore, if the
>standard were to require compile-time enforcement, then if the calling
>function has a non-default throw specification, it would be required to
>wrap those function calls in a try block with at least one handler that
>has catch(...). It would have been possible to require this, but very
>inconvenient.

Unfortunately unless and until compilers provide a compile time option
to check + a runtime option to suppress checking ES will be largely
ignored.  I realise that this is a QoI issue but it would be nice if the
Standards Committees could find a way to positively encourage
implementors to provide such options.


Francis Glassborow      Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Anders Pytte <anders@milkweed.com>
Date: 11 Sep 2000 10:39:27 -0400
Raw View
in article 8pbbn6$o5b$1@news6.svr.pol.co.uk, Martin Aspeli at
anakin24@bigfoot.com wrote on 9/10/00 1:13 AM:

>> Sorry to dig this up again. But when a colleague asked me, I could not
>> remember the reason(s) why the standard committee chose not to include
>> compile time enforcement of exception specifications.
>
> I'm not sure I understand exactly what you mean, but according to
> www.ootips.org, some people beleive that exception specifications are bad
> because they produce a dependency between the caller and the class itself.

I was asking specifically for the reasoning used by the committee to reject
compile time enforcement of exception specifications. I can think of
possible reasons myself, but I'm not the committee.

> Also, no exception specification means "all exceptions can be thrown", and
> in my view at least, there *should* be a way of doing so.

Not sure what this has to do with anything (or even what you mean).

> I'd also imagine that exception specifications introduce a (small)
> performance hit, but I'm far from sure about this.

If anything, compile time enforcement of exception specifications provides
performance benefits. For one thing, you could get rid of unexpected
exception handling; for another, the compiler could make certain
optimizations where it knew a function could not throw.

Anders.


--
Anders Pytte                                   Milkweed Software
PO Box 32                                  voice: (802) 586-2545
Craftsbury, VT 05826                  email: anders@milkweed.com
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Anders Pytte <anders@milkweed.com>
Date: 11 Sep 00 15:39:01 GMT
Raw View
in article slrn8rivqi.4c.juergen@monocerus.n-online.de, Juergen Heinzl at
juergen@monocerus.n-online.de wrote on 9/10/00 11:12 AM:

> In article <B5D8AE2A.B276%anders@milkweed.com>, Anders Pytte wrote:
>> Folks,
>>
>> Sorry to dig this up again. But when a colleague asked me, I could not
>> remember the reason(s) why the standard committee chose not to include
>> compile time enforcement of exception specifications.
> [-]
> See "The C++ Programming Language", 14.6.1.

Thanks for all who responded. To summarize, complete compile time
enforcement (a al Java) was deemed impractical because:

1. in large systems, especially where not all source code is available, we
want to reserve the ability to add an exception to a function without
forcing recompilation of the entire system (thus exception specifications
are not required to be checked across compilation-unit boundaries)

2. it would prevent us from "overriding" the compiler generated exception
specification in functions that called other functions that could throw, but
that we knew would never throw in the context of the calling function

Anders.



--
Anders Pytte                                   Milkweed Software
PO Box 32                                  voice: (802) 586-2545
Craftsbury, VT 05826                  email: anders@milkweed.com


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]