Alf P. Steinbach said:
:
[...]
in the standard here) std::bad_exception, throwing that. Most
experienced C++ programmers regard the empty exception
specification, and possibly but just possibly the specification
allowing std::exception, as the only useful specification(s).
Yeah. But
But?
Uhmm. Better understanding things. "But",
I looketh at tree first URLs, all postings from you, my friend.
Really? Your local google has some problems, I guess.
[...]
Could you perhaps summarize your views with no _parenthetical_
examples?
Here's a "copy&paste". Does this help?
David Butenhof wrote:
[...]
I see it three times, because that's how many times you typed it. (Was that
a trick question? ;-) )
;-)
Seriously, though, I think that's very much the crux of your argument, isn't
it?
Yep.
I would expect "hello" to be output by the POSIX cleanup handler as
c_f() is unwound in response to pthread_exit(). THAT is clearly specified
by current standards.
NO! 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);
}
< as an aside: Attila, do you follow me? >
I see almost-no-problems** catching and "finalizing" ANY of these
exceptions. If one can catch-and-finalize "thread termination" and
cause an abnormal process termination right after "finalizing" it,
I don't see why this can't be done by the implementation at throw
point due to ES violation.
**)
http://www.opengroup.org/austin/mailarchives/austin-group-l/msg05202.html
(Subject: XSH ERN 77, 81 and 82)
Now, though, we face what may be a philosophical issue, if it's not
carefully tied down by the C++ standard (which I haven't read, much less
analyzed in detail). If C++ is required to have 2-phase exceptions AND if
It isn't required, currently.
an implementation is not allowed to SEARCH (phase 1) through f()'s empty
throw() specification, then I would expect to see std::unexpected() fire
before the second "hello" can be written by o's destructor.
NO! Before the FIRST "hello"! (I know that you know that the answer
I wanted is a sort of /pthread_/null of "hello" ;-) ). Because the
"handler" inject by pthread_cleanup_push() shall be modeled upon
a C++ destructor, not archaic try/finally.
However, you have suggested that a single phase unwind implementation is
allowed, and in such an implementation I would expect o's destructor to
run, printing a second "hello", and THEN for std::unexpected() to fire as
the runtime attempts to unwind through the empty throw() specification.
Yes. Well, please take a loot at:
http://groups.google.com/[email protected]
(Subject: Exception handling... it's time to fix the standard)
I can tell you that the C++ implementation on both Tru64 UNIX and OpenVMS,
compiled and run with default options, print "hello" twice and THEN abort
with unexpected().
That's exactly what the C++ standard currently mandates, so to speak.
(Proving that, as I said, while OpenVMS has always
supported 2-phase exceptions and recommends cleanup on the unwind phase,
not everyone actually uses it that way. ;-) )
Yeah, unfortunately, that's seems to be true with respect to majority
of C++ committee members too.
I can also say that on Tru64 UNIX (I didn't bother going through the extra
gyrations to get and analyze a process core dump on OpenVMS), the core file
leads one to the f() frame (though there's terminate and abort and raise
and all that stuff on top of it) so that someone diagnosing the abort might
be lead to examine the f() function and notice the empty throw()
specification. (While OpenVMS reports that "terminate or unexpected" has
been invoked, on Tru64 you get only "Resources lost(coredump)".)
This at least meets my minimal requirements, that the cleanup and unwind be
properly synchronized. I'd be vexed at an implementation that maintained a
separate stack of cleanup handlers, for example, and called them without
actually unwinding the call stack, so that the final core file might show
c_f() as the active frame even though cleanup had occurred out through f().
I'd be annoyed if the core file showed NO active frames, because there'd be
no clue to what happened.
Yes.
I also understand that YOU would prefer that std::unexpected() would fire
without running ANY cleanup OR unwinding any frames as the SEARCH exception
pass (phase 1) ran up against the empty throw() specification.
YES!
I'm inclined to agree with you philosophically, but with one foot (plus a
heel of the other foot) planted firmly in the real world, I'd worry about
the consequences of breaking external invariants by suddenly adding a
requirement that ~o() not be run in this case. Even your trivial example
shows where this could cause problems, because you do have an external
invariant. The output of this program might be redirected into a file that
might be used as a benchmark for testing (or for other purposes),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Oh,
http://groups.google.com/[email protected]
#include <cassert> // The C++ stuff
#include <stdio.h> // The POSIX one
#include "errbutt" // That's my own
int main() {
int rc;
rc = printf("Hello World\n");
assert(rc);
if (rc < 0 || (rc = fclose(stdout)) == EOF) {
rc = errno;
assert(rc);
}
else {
assert(!rc);
}
return rc ? report_error(rc) : 0;
}
;-)
and the
change in output from "hello\nhello\n" to "hello\n" between one version of
the C++ runtime and another could indeed be an issue.
Yes, I understand. But please note that propagation of exceptions
(unwinding) when "no matching handler found" is implemention-defined
(well, ES aside) in the current C++ standard. Portably, folks just
can't rely on always-unwind... if they don't use catch(...) and/or
"current" version of ES. The funny thing is that exceptions specs
are considered sort-of "harmful" by many "prominent" members of the
C++ community and aren't recommended.
http://www.gotw.ca/publications/mill22.htm
http://www.boost.org/more/lib_guide.htm#Exception-specification
regards,
alexander.