Topic: Exception handling... it's time to fix the standard
Author: apm35@student.open.ac.uk (apm)
Date: Fri, 30 May 2003 18:15:26 +0000 (UTC) Raw View
terekhov@web.de (Alexander Terekhov) wrote in message news:<3ED3AE8B.AEDAD52A@web.de>...
> "Terje Sletteb " wrote:
> I want to
> have the standard-mandated 2-phase exception processing with the
> exception specs acting as simple "barriers" during the 1st/search
> phase. All unexpected/uncaught exceptions should result in the
> invocation of std::unexpected() at their throw-points; that's due
> to the implicit restrictive ESes that I want to be given to all
> destructors [throw()]
The difficulty is in having stronger ESes that work in the presence of
templates such as those used in the STL. See
http://www.andrewmarlow.co.uk/publications.html for a proposal on
stronger ESes including a discussion of these, and other, issues.
Regards,
Andrew M.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Fri, 30 May 2003 20:01:36 +0000 (UTC) Raw View
apm wrote:
>
> terekhov@web.de (Alexander Terekhov) wrote in message news:<3ED3AE8B.AEDAD52A@web.de>...
> > "Terje Sletteb " wrote:
> > I want to
> > have the standard-mandated 2-phase exception processing with the
> > exception specs acting as simple "barriers" during the 1st/search
> > phase. All unexpected/uncaught exceptions should result in the
> > invocation of std::unexpected() at their throw-points; that's due
> > to the implicit restrictive ESes that I want to be given to all
> > destructors [throw()]
>
> The difficulty is in having stronger ESes that work in the presence of
> templates such as those used in the STL.
Show me an example illustrating "the difficulty" with respect to
*destructors* having stronger (throw()-nothing) ESes, please.
> See
> http://www.andrewmarlow.co.uk/publications.html for a proposal on
> stronger ESes including a discussion of these, and other, issues.
Uhmm, http://www.marlowa.plus.com/publications.html perhaps?
http://www.marlowa.plus.com/goodies/proposal.pdf
(A proposal to add static checking to C++ exception specifications.)
I'm NOT asking for "an extension to C++ in the area of exception
handling that is designed to facilitate static checking of
exceptions."
I can bombard-you-to-death with links on that, but I'll refrain.
(hoping that you'll take a chance and try to understand what I'm
talking about in this thread ;-) )
regards,
alexander.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: tslettebo@chello.no.nospam ("Terje Sletteb ")
Date: Tue, 27 May 2003 17:21:02 +0000 (UTC) Raw View
"Alexander Terekhov" <terekhov@web.de> wrote in message
news:3EC0ECAA.6520B266@web.de...
I've read through your postings, but as they are long and detailed, with a
lot of references to other places, but without some kind of introduction
or summary, I found it hard to understand what your point was.
Could you have tried to restate what it is, in a introduction/summary
form?
This may also have contributed to lack of feedback to this thread, so far.
Regards,
Terje
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Tue, 27 May 2003 20:55:42 +0000 (UTC) Raw View
"Terje Sletteb=F8" wrote:
>=20
> "Alexander Terekhov" <terekhov@web.de> wrote in message
> news:3EC0ECAA.6520B266@web.de...
>=20
> I've read through your postings, but as they are long and detailed, wit=
h a
> lot of references to other places, but without some kind of introductio=
n
> or summary, I found it hard to understand what your point was.
>=20
> Could you have tried to restate what it is, in a introduction/summary
> form?
As currently specified, exception specs not only catch unexpected=20
exceptions, but they also invoke "wrong" unexpected/terminate=20
handlers -- those that were in effect at throw-points (handlers=20
basically fly together with the unexpected exceptions). I want to=20
have the standard-mandated 2-phase exception processing with the=20
exception specs acting as simple "barriers" during the 1st/search=20
phase. All unexpected/uncaught exceptions should result in the=20
invocation of std::unexpected() at their throw-points; that's due=20
to the implicit restrictive ESes that I want to be given to all=20
destructors [throw()] and "threads" -- those should only throw=20
thread cancel/exit exceptions (things like exceptions with=20
throwing copy constructors, thowing atexit() handlers, and etc.=20
aside for a moment]. More "refinements" can be done if/once we=20
agree on that.
regards,
alexander.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Sun, 25 May 2003 14:18:56 +0000 (UTC) Raw View
< "self-correction" [well, and "move up" ;-) ] >
> > Finally, I believe
> > that the standard should say that 'execution of each and
> > every thread' [initial/main including] shall be done "as if"
> >
> > whatever run(...whatever...) throw(std::thread_exit,
> > std::thread_cancel);
>
> Sorry, std::thread_exit_request and std::thread_cancel_request
> (std::thread_termination_request aside for a moment ;-) ):
>
> http://groups.google.com/groups?selm=3EC258F8.AE7DF214%40web.de
>
> <quote>
>
> I can see nothing in the POSIX standard that would prohibit
> the following implementation of pthread_exit():
>
> extern "C" void pthread_exit(void * ptr) {
> std::thread_exit(ptr);
> }
Sorry, I meant:
#define PTHREAD_CANCELED std::thread_canceled()
extern "C" void pthread_exit(void * ptr) throw(std::thread_termination_request) {
(ptr == PTHREAD_CANCELED) ? std::thread_cancel() : std::thread_exit(ptr);
}
>
> using something along the lines of: (from the "std" namespace)
struct thread_canceled {
operator void * () { return &unique; }
static thread_canceled unique;
};
>
> class thread_termination_request : public std::exception ...
> class thread_cancel_request : public std::thread_termination_request ...
> class thread_exit_request : public std::thread_termination_request ...
>
> template<typename T>
> class thread_exit_value : public std::thread_exit_request ...
>
> template<typename T>
> void thread_exit(T value) {
> assert(std::thread_self().can_exit_with<T>());
> throw thread_exit_value(value);
> }
template<>
void thread_exit(std::thread_canceled) {
thread_cancel();
}
void thread_cancel() {
throw std::thread_cancel_request();
}
("or something like that").
regards,
alexander.
--
"Stroustrup is not a disinterested party in that debate."
-- [Subject: Re: c#] http://tinyurl.com/ckem
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Thu, 15 May 2003 21:02:45 +0000 (UTC) Raw View
Alexander Terekhov wrote:
[...]
> Finally, I believe
> that the standard should say that 'execution of each and
> every thread' [initial/main including] shall be done "as if"
>
> whatever run(...whatever...) throw(std::thread_exit,
> std::thread_cancel);
Sorry, std::thread_exit_request and std::thread_cancel_request
(std::thread_termination_request aside for a moment ;-) ):
http://groups.google.com/groups?selm=3EC258F8.AE7DF214%40web.de
<quote>
I can see nothing in the POSIX standard that would prohibit
the following implementation of pthread_exit():
extern "C" void pthread_exit(void * ptr) {
std::thread_exit(ptr);
}
using something along the lines of: (from the "std" namespace)
class thread_termination_request : public std::exception ...
class thread_cancel_request : public std::thread_termination_request ...
class thread_exit_request : public std::thread_termination_request ...
template<typename T>
class thread_exit_value : public std::thread_exit_request ...
template<typename T>
void thread_exit(T value) {
assert(std::thread_self().can_exit_with<T>());
throw thread_exit_value(value);
}
</quote>
>
> is called; that implementation simply does finalization
> of thread_exit or thread_cancel exception (if thrown)
> resulting in thread termination and that any other uncaught
> exception will end up in std::unexpected() invoked at throw
> point.
I forgot to mention:
- make std::unexpected handlers thread-specific (keep
std::terminate handers "enclave-wide")
- get rid of the totally broken "if called by the
implementation" clause in 18.6.2.4/2. Details can
be found in a thread here: <http://tinyurl.com/btje>
(with std::unexpected invoked at throw point, there
will be no difference at all with respect "if called
by the program" or by the implementation)
- "weaken" function-try-block handlers for non-dtors
(having implicit throw() ES, function-try-block for
a dtor doesn't make sense). "weaken" means that it
shall be "invisible" in the search phase and have
"dtor-like" semantics during unwinding ala(*):
<copy&paste>
I'll admit that I'll have no problems with something like
template<class _FwdIt, class _Tval> inline
void _Uninit_fill(_FwdIt _First, _FwdIt _Last, const _Tval& _Val,
_Nonscalar_ptr_iterator_tag)
{ // copy _Val throughout raw [_First, _Last), arbitrary type
_FwdIt _Next = _First;
try {
for (; _First != _Last; ++_First)
_Construct(&*_First, _Val);
}
action_on_propagation_of(...) { /* THIS DOESN'T CATCH *UNEXPECTED* EXCEPTIONS */
/* THIS DOES RETHROW EXCEPTIONS AUTOMATICALLY */
/* NOTHING ELSE CAN BE THROWN FROM THIS SCOPE */
for (; _Next != _First; ++_Next)
_Destroy(&*_Next);
}
}
</copy&paste>
more info on this: <http://tinyurl.com/bthu>.
regards,
alexander.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Tue, 13 May 2003 15:11:04 +0000 (UTC) Raw View
G'Day,
A) http://tinyurl.com/bdp1
"Arrgh! Now I understand why you are unhappy about this.
This goes against everything I'd understood about the way
exceptions worked."
B) <Forward Inline>
<-------- Original Message -------->
Message-ID: <3EC0E634.D5B14ACB@web.de>
Newsgroups: comp.lang.c++
Subject: Re: does throw() imply any type of performance difference?
stephan beal wrote:
>
> Hello!
>
> i've got a high-usage class which i'm trying to optimize a bit, and i have a
> question about the throw() clause:
>
> class Foo {
> inline void foo() throw() {...};
> };
>
> Question: does the addition of throw() give a compiler any implicit
> permission (or leeway) to add any sort of exception-handling code to that
> function. More precisely, does the inclusion of this keyword, in and of
> itself, it allow the compiler to make any changes which might affect the
> runtime performance of function foo(), compared to the output generated
> when foo() does not throw()? (The point being, if it does then i want to
> remove them from this particular class.)
>
> i would greatly appreciate any clarification on that point.
Unfortunately, throw() implies [due to totally broken semantics
specified in the {current} C++ standard] a function-try-block with
catch(...) handler that invokes std::unexpected(). Broken standard
aside for a moment(*), throw() really-really helps optimizers. Buy
and read the following paper:
http://www.computer.org/concurrency/pd2000/p4072abs.htm
("C++ Exception Handling", Christophe de Dinechin,
IEEE Concurrency October-December 2000 (Vol. 8, No. 4))
<abstract>
The C++ programming language offers a feature known as exception
handling, which is used, for instance, to report error conditions.
This technique can result in more robust software. On the other
hand, it generally has a highly negative performance impact, even
when exceptions are not actually thrown. This impact is especially
important on an architecture such as the HP/Intel IA-64 processor,
which is very sensitive to compiler optimizations. Hewlett-Packard
implemented exception handling for IA-64 in a way that leaves the
door open for optimizations, even in the presence of exceptions.
</abstract>
regards,
alexander.
The "right" approach is this:
http://groups.google.com/groups?threadm=3EBA6888.D4DF2AB1%40web.de
(Subject: Re: __attribute__((cleanup(function)) versus try/finally)
"....
The current C++ standard says:
"The process of calling destructors for automatic objects
constructed on the path from a try block to a throw-expression
is called 'stack unwinding.'"
That's okay (there's a nice definition of 'try-block' as well).
Now, the current C++ standard also has a couple of kinda-relevant
"implementation-defined" bits:
a) "If no matching handler is found in a program, the function
terminate() is called; whether or not the stack is unwound
before this call to terminate() is implementation-defined",
b) "In the situation where no matching handler is found, it is
implementation-defined whether or not the stack is unwound
before terminate() is called.".
and it also defines the semantics of exception specifications...
in effect, as just a bunch of noop/rethrowing function-try-block
catch-handlers with a trailing catch(...)-thing that invokes
std::unexpected().
I just hate that. To begin with, the definition of the term
'stack unwinding' makes me wonder what "try-block" is meant
here:
int main() {
object o; // <-- 'unwinding' is implementation-defined
throw "trouble";
}
and here:
void Main() throw() {
object o; // <-- 'unwinding' is REQUIRED here
throw "trouble";
}
I believe that in both cases above, std::unexpected() shall
be invoked as the result of successful evaluating of throw-
expression and without any 'unwinding' taking place. Further,
I believe that ALL dtors shall have an implicit throw()-
nothing exception-spec imposed on them. Finally, I believe
that the standard should say that 'execution of each and
every thread' [initial/main including] shall be done "as if"
whatever run(...whatever...) throw(std::thread_exit,
std::thread_cancel);
is called; that implementation simply does finalization
of thread_exit or thread_cancel exception (if thrown)
resulting in thread termination and that any other uncaught
exception will end up in std::unexpected() invoked at throw
point.
...."
</-------- Original Message -------->
C) http://google.com/groups?selm=3C91397A.9FC5F5A4%40web.de
(Subject: Re: C++ and threads)
<quote>
"The process of calling destructors for automatic
objects constructed on the path from a try block
to a throw-expression is called 'stack unwinding.'"
> In the original DCE exception package, which was a set of
> C macros (over setjmp/longjmp),
OK, you probably mean something along the lines of:
ftp://ftp.opengroup.org/pub/dce122/dce/src/threads.tar.gz
"exc handling.h 46591 05/10/96 14:35
exc handling.c 37966 05/10/96 14:35"
> any frame with a TRY/CATCH would unwind even if it had no
> interest in the exception being propagated. That is, it had
> to unwind just to find out.
Question:
Are you saying that it is practically impossible (or perhaps
just pointless/silly) to try to "arrange" the C-macros/
jmp-based exception handling such that when the control
enters the try block/scope you have already "registered"
the "identity" of catch{ all} handlers in the "try context
block" structure as well... so that it could be easily
checked (i.e the presence of next matching handler
somewhere on the "stack") at *throw/re-throw* point(s),
PRIOR to "unwinding"/longjmp-ing to the next frame?
</quote>
Now, what am I missing and/or misunderstanding? TIA.
regards,
alexander.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]