From: Seungbeom Kim on
Goran wrote:
>
> I think that you misunderstood this, and I think that's because you
> fail (or refuse?) to accept what throw() does. By writing throw(), I
> am NOT saying "this does not throw". I am saying "if this throws, I
> die". That's a BIG difference.

But from the caller's perspective, they are equivalent because the caller
doesn't notice a thrown exception. Dying rather than actually throwing
an exception is a way for the callee to meet the requirement/contract
that it will not throw.

On the other hand, "this returns normally without throwing" is certainly
different from "if this throws, I die", because the former doesn't allow
not returning whereas the latter does.

So we have many ways to "finish" a function:

(a) to return normally (without throwing)
(b) to throw an exception
(c) to terminate the program (by exit, abort, or exec family)
(d) to keep going without ever finishing (e.g. by an infinite loop)

and throw() guarantees only that (b) will not happen.

--
Seungbeom Kim

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Nevin :-] Liber on
In article <4b748f32$0$283$14726298(a)news.sunsite.dk>,
DeMarcus <use_my_alias_here(a)hotmail.com> wrote:

> Today this
> no-throw issue is a problem for at least three reasons.
>
> * It's stressful to do a thorough no-throw investigation since the
> compiler won't help you.
> * It's way too easy to accidentally throw from a no-throw function
> without any warning from the compiler.
> * Since the compiler doesn't warn you, design flaws can easy slip
> through and survive until a refactoring would cost as much as rewriting
> the whole application.

You say that, but you don't mention any projects where these problems
indeed show up. What open source projects, for instance, suffer from
these issues?

If these are real, practical problems, I'd like to see the code to try
and understand why people are having these issues, because I just don't
see them. Your experience doesn't seem to match mine.

Again, I'm not looking for contrived, theoretical problems, but issues
people are having today in real code.

--
Nevin ":-)" Liber <mailto:nevin(a)eviloverlord.com> 773 961-1620

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Seungbeom Kim on
ThosRTanner wrote:
> On Feb 11, 1:16 am, "Nevin :-] Liber" <ne...(a)eviloverlord.com> wrote:
>> In article
>> <82be602f-bb4e-45af-a04e-fcbeee7fd...(a)z17g2000yqh.googlegroups.com>,
>> ThosRTanner <ttann...(a)bloomberg.net> wrote:
>>> It is trivially easy to statically analyse whether or not a function
>>> might throw. You can even tell precisely what it might throw.
>> Not without whole program analysis.
>
> No. It is trivial. What a function can throw is the union of the
> exception specifications of all the functions it calls, and all the
> throws it executes. A function without an exception specification can
> throw anything. An extern "C" function should throw nothing as it
> breaks the contract of being callable by C if it does that.

Then it quickly becomes useless because you assume a called function
can throw anything and all you can assert about the calling function
is that it can throw anything. Especially with templates or functors.

--
Seungbeom Kim

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: ThosRTanner on
On Feb 12, 7:34 am, Seungbeom Kim <musip...(a)bawi.org> wrote:
> ThosRTanner wrote:
> > On Feb 11, 1:16 am, "Nevin :-] Liber" <ne...(a)eviloverlord.com> wrote:
> >> In article
> >> <82be602f-bb4e-45af-a04e-fcbeee7fd...(a)z17g2000yqh.googlegroups.com>,
> >> ThosRTanner <ttann...(a)bloomberg.net> wrote:
> >>> It is trivially easy to statically analyse whether or not a function
> >>> might throw. You can even tell precisely what it might throw.
> >> Not without whole program analysis.
>
> > No. It is trivial. What a function can throw is the union of the
> > exception specifications of all the functions it calls, and all the
> > throws it executes. A function without an exception specification can
> > throw anything. An extern "C" function should throw nothing as it
> > breaks the contract of being callable by C if it does that.
>
> Then it quickly becomes useless because you assume a called function
> can throw anything and all you can assert about the calling function
> is that it can throw anything. Especially with templates or functors.
>
The same would be true for const if it was runtime checked.

It's easy to do static checking of throw specifications at compile
time because the compiler knows the throw spec of all the called
functions, because it has to see the prototype before it can compile
the call. Now, whether or not it is helpful for no throw spec to mean
the function can throw anything is another question entirely.

It's not useless - you just have to tighten your throw specs up from
the bottom upwards.

However, I know that this:

void randomfunc():

void fred() throw()
{
randomfunc();
}

can potentially crash. So I can't use it. It's no use saying "I know
that randomfunc() doesn't throw", because someone might change
randomfunc(). There's nothing in the compiler that'll stop them doing
it. And my program will terminate unexpectedly. And that is entirely
useless.

If the compiler error'd that sort of thing, I'd be unbelievably happy,
because throw specs would be of some use, rather than adding a whole
load of code to the executable with the express purpose of terminating
my program because I'd broken the interface guarantee made by the
prototype.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Goran on
On Feb 12, 8:34 am, Seungbeom Kim <musip...(a)bawi.org> wrote:
> Goran wrote:
>
> > I think that you misunderstood this, and I think that's because you
> > fail (or refuse?) to accept what throw() does. By writing throw(), I
> > am NOT saying "this does not throw". I am saying "if this throws, I
> > die". That's a BIG difference.
>
> But from the caller's perspective, they are equivalent because the caller
> doesn't notice a thrown exception. Dying rather than actually throwing
> an exception is a way for the callee to meet the requirement/contract
> that it will not throw.

Yes, but the target of throw() is bigger than any particular caller:
if it fires e.g. unexpected(), something is so seriously wrong with
the program that any particular caller is irrelevant.

> On the other hand, "this returns normally without throwing" is certainly
> different from "if this throws, I die", because the former doesn't allow
> not returning whereas the latter does.
>
> So we have many ways to "finish" a function:
>
> (a) to return normally (without throwing)
> (b) to throw an exception
> (c) to terminate the program (by exit, abort, or exec family)
> (d) to keep going without ever finishing (e.g. by an infinite loop)
>
> and throw() guarantees only that (b) will not happen.

I think that you just perverted the course of justice ;-).

What I wrote up there is (what I think is) the purpose of throw():
it's merely a way to specify that an exception from a particular
function is so unexpected that program should die. Of course, standard
offers options, but if you go with a, d, you are perverting throw();
options should only be used to... ahem... "enhance" on default
behavior, not significantly change it. IOW, a and d are a case of
"just because you can, doesn't mean you should".

Goran.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]