This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [rfc] fix libstdc++/10606
Benjamin Kosnik wrote:
...
For the lazy among us, can you post the test code for constructing
that table please?
I don't have the original code anymore but the attached program
should be close enough. I just quickly whipped it up so be kind
to me if it's buggy :)
Also, this clarifies/simplifies uncaught_exception to something that
means true when an exception object (not temporary object) is "in
flight." I like that part.
Just so there's no misunderstanding: by the temporary object I meant
the unnamed object constructed by the runtime library as a copy of
the value of argument of the throw-expression. I.e., in this snippet:
try {
S s0, s1;
throw 1 ? s0 : s1; // invokes S(const S&) with s0 as argument
}
catch (...) {
throw; // rethrows s2
}
s0 is the /thrown object/. The unnamed temporary object created
by the runtime by invoking the copy ctor for S is known as the
/exception object/ (let's call it s2). The issue proposes to
make it clear that uncaught_exception() returns *false* until
the completion of the evaluation of the expression 1 ? s0 : s1,
and *true* immediately after that, i.e., true in the copy ctor
invoked to copy s0 to s2. This copy is what I would call the
object "in flight" because that's what gets caught by handlers
that catch by reference and what gets rethrown from such handlers
by a throw expression with no operands.
Martin
#include <stdio.h>
#include <exception>
static int n;
struct B {
int id;
B (): id (n++) {
printf ("%d: B::B() [%d]\n", std::uncaught_exception (), id);
}
B (const B&);
~B () {
printf ("%d: ~B::~B() [%d]\n", std::uncaught_exception (), id);
}
};
struct D: B
{
D (): B () {
printf ("%d: D::D() [%d]\n", std::uncaught_exception (), id);
}
D (const B &b): B (b) {
printf ("%d: %D::%D(const %D& [%d]) [%d]\n",
std::uncaught_exception (), b.id, id);
}
D (const D &d): B (d) {
printf ("%d: %D::%D(const %D& [%d]) [%d]\n",
std::uncaught_exception (), d.id, id);
}
~D () {
printf ("%d: ~D::~D() [%d]\n", std::uncaught_exception (), id);
}
};
B::B (const B &b)
: id (n++)
{
printf ("%d: B::B(const B& [%d]) [%d]\n",
std::uncaught_exception (), b.id, id);
static int rethrow;
if (!rethrow++) {
printf (" throw D\n");
throw D (*this);
}
}
int main ()
{
try {
try {
B b;
printf ("throw B\n");
throw b;
}
catch (B b) {
printf ("%d: caught B [%d], rethrowing\n",
std::uncaught_exception (), b.id);
throw;
}
}
catch (B b) {
printf ("%d: caught B [%d]\n", std::uncaught_exception (), b.id);
}
}