Topic: Defect Report: implicitly declared member function, noexcept or throw(), ambiguous.


Author: Yakov Galka <ybungalobill@gmail.com>
Date: Wed, 22 Jun 2011 01:30:27 CST
Raw View
N3290, "15.4 Exception specifications [except.spec], (14)" says:

An implicitly declared special member function (Clause 12) shall have
an exception-specification. If f is
an implicitly declared default constructor, copy constructor, move
constructor, destructor, copy assignment
operator, or move assignment operator, its implicit exception-
specification specifies the type-id T if and only
if T is allowed by the exception-specification of a function directly
invoked by f   s implicit definition; 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.

If it happens to allow no exceptions, should it be semantically
equivalent to a dynamic-exception-specification and call
std::unexpected, or to noexept(true) and call std::terminate directly?

It does matter in the following case:

struct X { ~X() { throw 0; } };

Here, according to "12.4 Destructors [class.dtor]", the above
paragraph applies. So ~X gets a non-throwing exception-specification.

struct X { ~X() noexcept { throw 0; } };
struct X { ~X() throw() { throw 0; } };

Which one?

--
Yakov Galka


--
[ 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: =?windows-1252?Q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Wed, 22 Jun 2011 08:22:47 CST
Raw View
On 2011-06-22 09:30, Yakov Galka wrote:
>
> N3290, "15.4 Exception specifications [except.spec], (14)" says:
>
> An implicitly declared special member function (Clause 12) shall have
> an exception-specification. If f is
> an implicitly declared default constructor, copy constructor, move
> constructor, destructor, copy assignment
> operator, or move assignment operator, its implicit exception-
> specification specifies the type-id T if and only
> if T is allowed by the exception-specification of a function directly
> invoked by f   s implicit definition; 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.
>
> If it happens to allow no exceptions, should it be semantically
> equivalent to a dynamic-exception-specification and call
> std::unexpected, or to noexept(true) and call std::terminate directly?
>
> It does matter in the following case:
>
> struct X { ~X() { throw 0; } };
>
> Here, according to "12.4 Destructors [class.dtor]", the above
> paragraph applies. So ~X gets a non-throwing exception-specification.
>
> struct X { ~X() noexcept { throw 0; } };
> struct X { ~X() throw() { throw 0; } };
>
> Which one?

This has already been reported at earlier occasions, search e.g. for the
thread "DR: How do implicit exception declarations (dis)allow
exceptions?" in this group and has already been forwarded to the core
working group.

Thanks & Greetings from Bremen,

- Daniel Kr   gler


--
[ 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: =?ISO-8859-2?Q?Andrzej_Krzemie=F1ski?= <akrzemi1@gmail.com>
Date: Wed, 22 Jun 2011 08:23:48 CST
Raw View
On Jun 22, 9:30 am, Yakov Galka <ybungalob...@gmail.com> wrote:
> N3290, "15.4 Exception specifications [except.spec], (14)" says:
>
> An implicitly declared special member function (Clause 12) shall have
> an exception-specification. If f is
> an implicitly declared default constructor, copy constructor, move
> constructor, destructor, copy assignment
> operator, or move assignment operator, its implicit exception-
> specification specifies the type-id T if and only
> if T is allowed by the exception-specification of a function directly
> invoked by f s implicit definition; 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.
>
> If it happens to allow no exceptions, should it be semantically
> equivalent to a dynamic-exception-specification and call
> std::unexpected, or to noexept(true) and call std::terminate directly?
>
> It does matter in the following case:
>
> struct X { ~X() { throw 0; } };
>
> Here, according to "12.4 Destructors [class.dtor]", the above
> paragraph applies. So ~X gets a non-throwing exception-specification.
>
> struct X { ~X() noexcept { throw 0; } };
> struct X { ~X() throw() { throw 0; } };
>
> Which one?

Hi, the paragraph you quote only says about implicitly generated
member functions. Note that for implicitly generated member functions
two observations apply:
1. When compiler (rather than programmer) detects that the member
function does not throw, it really does not throw (there is no way
std::terminate or std::unexpected is called due to violated noexcept
or throw() ).
2. Implicitly generated functions do not have bodies, so your examples
(with a throw in the function body) do not apply to this paragraph.

Also note that noexcept(true) and throw() are compatible in the sense
that:
1. noexcept operator will work the same for either
2. the "nothrow" traits like std::is_nothrow_move_constructible will
work the same for either

(I described it in my article:
http://akrzemi1.wordpress.com/2011/06/10/using-noexcept/)

So, whatever the compiler chooses for implicitly generated member
functions, you will not be able to tell the difference. Thus, under
the as-if rule, compiler is anyway allowed to switch between the two
at random, and therefore specifying which one it should choose is not
necessary.

Regards,
&rzej


--
[ 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: Yakov Galka <ybungalobill@gmail.com>
Date: Thu, 23 Jun 2011 13:46:22 CST
Raw View
On Jun 22, 5:22 pm, Daniel Kr   gler <daniel.krueg...@googlemail.com>
wrote:
> On 2011-06-22 09:30, Yakov Galka wrote:
>
>
> > N3290, "15.4 Exception specifications [except.spec], (14)" says:
>
> > An implicitly declared special member function (Clause 12) shall have
> > an exception-specification. If f is
> > an implicitly declared default constructor, copy constructor, move
> > constructor, destructor, copy assignment
> > operator, or move assignment operator, its implicit exception-
> > specification specifies the type-id T if and only
> > if T is allowed by the exception-specification of a function directly
> > invoked by f s implicit definition; 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.
>
> > If it happens to allow no exceptions, should it be semantically
> > equivalent to a dynamic-exception-specification and call
> > std::unexpected, or to noexept(true) and call std::terminate directly?
>
> > It does matter in the following case:
>
> > struct X { ~X() { throw 0; } };
>
> > Here, according to "12.4 Destructors [class.dtor]", the above
> > paragraph applies. So ~X gets a non-throwing exception-specification.
>
> > struct X { ~X() noexcept { throw 0; } };
> > struct X { ~X() throw() { throw 0; } };
>
> > Which one?
>
> This has already been reported at earlier occasions, search e.g. for the
> thread "DR: How do implicit exception declarations (dis)allow
> exceptions?" in this group and has already been forwarded to the core
> working group.
>
> Thanks & Greetings from Bremen,
>
> - Daniel Kr gler

Ohh, I'm sorry. I've searched for "Defect Report" and couldn't find
anything relevant because it starts with "DR".

On Jun 22, 5:23 pm, Andrzej Krzemie   ski <akrze...@gmail.com> wrote:
> On Jun 22, 9:30 am, Yakov Galka <ybungalob...@gmail.com> wrote:
>
> > N3290, "15.4 Exception specifications [except.spec], (14)" says:
>
> > An implicitly declared special member function (Clause 12) shall have
> > an exception-specification. If f is
> > an implicitly declared default constructor, copy constructor, move
> > constructor, destructor, copy assignment
> > operator, or move assignment operator, its implicit exception-
> > specification specifies the type-id T if and only
> > if T is allowed by the exception-specification of a function directly
> > invoked by f s implicit definition; 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.
>
> > If it happens to allow no exceptions, should it be semantically
> > equivalent to a dynamic-exception-specification and call
> > std::unexpected, or to noexept(true) and call std::terminate directly?
>
> > It does matter in the following case:
>
> > struct X { ~X() { throw 0; } };
>
> > Here, according to "12.4 Destructors [class.dtor]", the above
> > paragraph applies. So ~X gets a non-throwing exception-specification.
>
> > struct X { ~X() noexcept { throw 0; } };
> > struct X { ~X() throw() { throw 0; } };
>
> > Which one?
>
> Hi, the paragraph you quote only says about implicitly generated
> member functions. Note that for implicitly generated member functions
> two observations apply:
> 1. When compiler (rather than programmer) detects that the member
> function does not throw, it really does not throw (there is no way
> std::terminate or std::unexpected is called due to violated noexcept
> or throw() ).
> 2. Implicitly generated functions do not have bodies, so your examples
> (with a throw in the function body) do not apply to this paragraph.
>
> Also note that noexcept(true) and throw() are compatible in the sense
> that:
> 1. noexcept operator will work the same for either
> 2. the "nothrow" traits like std::is_nothrow_move_constructible will
> work the same for either
>
> (I described it in my article:http://akrzemi1.wordpress.com/2011/06/10/using-noexcept/)
>
> So, whatever the compiler chooses for implicitly generated member
> functions, you will not be able to tell the difference. Thus, under
> the as-if rule, compiler is anyway allowed to switch between the two
> at random, and therefore specifying which one it should choose is not
> necessary.
>
> Regards,
> &rzej
>

There is one (and only one) exception to what you said, "12.4
Destructors [class.dtor]":

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 (15.4).

--
Yakov Galka


--
[ 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                      ]