Topic: DR: How do implicit exception declarations (dis)allow exceptions?
Author: CornedBee <wasti.redl@gmx.net>
Date: Sun, 20 Mar 2011 14:20:44 CST Raw View
[except.spec]p14 says:
"f shall allow all exceptions if any function it directly invokes
allows all exceptions, and f shall allow no exceptions if every
function it directly invokes allows no exceptions."
In C++03, the meaning of the above was clear: "allow all exceptions"
means no specification, "allow no exceptions" means throw().
In C++0x, there are new ways to express the same intent:
noexcept(false) and noexcept(true), respectively.
It is not important to distinguish between no specification and
noexcept(false), since the two are semantically equivalent for
functions that cannot have redeclarations (which implicit functions
cannot have).
However, throw() calls unexpected() if an exception occurs, while
noexcept(true) calls terminate(). The standard does not define which
of the two methods is used to allow no exceptions.
In reality, it shouldn't matter, since for an implicitly defined
function that allows no exceptions, there truly can be no exception
that tries to escape the function. But it feels wrong not to specify
it.
>From a compatibility standpoint, it's better to leave it where it was
in C++03: allow no exceptions means throw() (which is also what the
code example in the standard says in a comment). But since the only
difference is the call to unexpected() instead of terminate(), and as
discussed above there isn't really a difference here, this argument is
weak.
On the other hand, dynamic exception specifications have been
deprecated, so it doesn't feel right to make implicit specifications
contain them.
Clang currently implements it thus: if any implicitly invoked function
is throw(), the resulting specification is throw(). But if all are
noexcept(true), so is the result. In other words, throw() is
considered the more lenient specification.
Regards,
Sebastian
--
[ comp.std.c++ is moderated. To submit articles, try posting with your ]
[ newsreader. If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: CornedBee <wasti.redl@gmx.net>
Date: Thu, 31 Mar 2011 13:49:06 CST Raw View
On Mar 20, 10:20 pm, CornedBee <wasti.r...@gmx.net> wrote:
> However, throw() calls unexpected() if an exception occurs, while
> noexcept(true) calls terminate(). The standard does not define which
> of the two methods is used to allow no exceptions.
> In reality, it shouldn't matter, since for an implicitly defined
> function that allows no exceptions, there truly can be no exception
> that tries to escape the function. But it feels wrong not to specify
> it.
Turns out that it actually does matter. [class.dtor]p3 says:
"A declaration of a destructor that does not have an exception-
specification is implicitly considered to have the same exception-
specification as an implicit declaration."
So the outcome of this DR decides whether this little example:
struct S {
~S() { throw 0; }
};
dies with a call to std::unexpected or std::terminate.
Sebastian
--
[ comp.std.c++ is moderated. To submit articles, try posting with your ]
[ newsreader. If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =3D?ISO-8859-1?Q?Daniel_Kr=3DFCgler?=3D <daniel.kruegler@googlemail.c=.om>
Date: Thu, 31 Mar 2011 13:49:53 CST Raw View
[Resend after 24 h]
Am 20.03.2011 21:20, schrieb CornedBee:
>
> [except.spec]p14 says:
> "f shall allow all exceptions if any function it directly invokes
> allows all exceptions, and f shall allow no exceptions if every
> function it directly invokes allows no exceptions."
>
> In C++03, the meaning of the above was clear: "allow all exceptions"
> means no specification, "allow no exceptions" means throw().
> In C++0x, there are new ways to express the same intent:
> noexcept(false) and noexcept(true), respectively.
>
> It is not important to distinguish between no specification and
> noexcept(false), since the two are semantically equivalent for
> functions that cannot have redeclarations (which implicit functions
> cannot have).
> However, throw() calls unexpected() if an exception occurs, while
> noexcept(true) calls terminate(). The standard does not define which
> of the two methods is used to allow no exceptions.
> In reality, it shouldn't matter, since for an implicitly defined
> function that allows no exceptions, there truly can be no exception
> that tries to escape the function. But it feels wrong not to specify
> it.
Yes, I agree.
>> From a compatibility standpoint, it's better to leave it where it was
> in C++03: allow no exceptions means throw() (which is also what the
> code example in the standard says in a comment). But since the only
> difference is the call to unexpected() instead of terminate(), and as
> discussed above there isn't really a difference here, this argument is
> weak.
> On the other hand, dynamic exception specifications have been
> deprecated, so it doesn't feel right to make implicit specifications
> contain them.
>
> Clang currently implements it thus: if any implicitly invoked function
> is throw(), the resulting specification is throw(). But if all are
> noexcept(true), so is the result. In other words, throw() is
> considered the more lenient specification.
Looks like a good approach to me. During the Madrid meeting the
proposed resolutions of the related issues
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1073
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1216
became accepted. Those will resolve some, but not all examples that
you are describing. It seems unclear to me whether in the scenario
struct A { ~A() throw() { } };
struct B { ~B() noexcept { } };
struct C : A, B { ~C() { throw 0; } };
the throwing destructor of C will invoke std::unexpected or not. This
is so, because the special destructor rule in 12.4 [class.dtor] p. 3
refers back to 15.4 [except.spec] which should deduce the exception
specification according to 15.4 p. 14. The latter seems to be unclear
about the effective exception specification in this example as you
describe.
HTH & Greetings from Bremen,
Daniel Kr=FCgler
--
[ comp.std.c++ is moderated. To submit articles, try posting with your ]
[ newsreader. If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]