Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

std::vector and destructor noexcept

40 views
Skip to first unread message

Juha Nieminen

unread,
Oct 21, 2016, 6:25:19 AM10/21/16
to
For std::vector to use the move constructor of its elements, said
constructor must have been declared 'noexcept'. However, does the
destructor of the element also need to be 'noexcept'?

I'm getting conflicting information on this. Many online discussions
claim that the destructor also needs to be 'noexcept', yet when I make
a test using a class with a non-noexcept destructor using the latest
gcc, std::vector calls the move constructor just fine.

(This question is quite relevant because the class I'm making does
allocate memory and needs to dispose it properly in its destructor,
and I'm not sure it's kosher to make it 'noexcept' in this case.)

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---

SG

unread,
Oct 21, 2016, 9:26:42 AM10/21/16
to
On Friday, October 21, 2016 at 12:25:19 PM UTC+2, Juha Nieminen wrote:
> For std::vector to use the move constructor of its elements, said
> constructor must have been declared 'noexcept'. However, does the
> destructor of the element also need to be 'noexcept'?

It should be in general. Destructors that throw exceptions are usually
difficult to deal with correctly and best be avoided.

This doesn't have anything to do with moving, though. Moving objects
around instead of copying them doesn't change the number of destructor
invocations. vector<T> might require T to have a no except dtor, I
don't know. I wouldn't be surprized if a throwing ~T would invoke
udefined behaviour when used in vector<T>. But I'd have to check that.

Cheers!
SG

Öö Tiib

unread,
Oct 21, 2016, 9:36:51 AM10/21/16
to
On Friday, 21 October 2016 13:25:19 UTC+3, Juha Nieminen wrote:
> For std::vector to use the move constructor of its elements, said
> constructor must have been declared 'noexcept'. However, does the
> destructor of the element also need to be 'noexcept'?

My streetwise assumption (can't cite scripture) is that
"Yes it is required".

>
> I'm getting conflicting information on this. Many online discussions
> claim that the destructor also needs to be 'noexcept', yet when I make
> a test using a class with a non-noexcept destructor using the latest
> gcc, std::vector calls the move constructor just fine.

How did you achieve in your test that the destructor was throwing?
Implicitly those are 'noexcept(true)' unless the class has any bases
or members that got 'noexcept(false)' destructors.

Alf P. Steinbach

unread,
Oct 21, 2016, 10:10:30 AM10/21/16
to
As long as the compilers you use support it, the main question is
whether a destructor of a moved-from object ever can throw?

If it can then it can really mess up buffer replacement code in
std::vector; formally that's then UB.

But otherwise, if the compilers support it, the question is one of
portability, if the /standard/ supports it. I don't know. But I would
think that since it is of practical interest to have that support, it
probably does?


Cheers!,

- Alf


Paavo Helde

unread,
Oct 21, 2016, 10:20:39 AM10/21/16
to
What is important for element moving is probably that the destructor of
*moved-away* elements does not throw exceptions. However, this cannot be
codified formally, so gcc might just assume that this is the case.

Anyway, this is only a theoretical issue because destructors of most
classes should be noexcept anyway, to avoid calling std::terminate()
during stack unwind. Add a try ... catch(...) block and log any
unexpected exceptions to stderr if there is no other way to make the
destructor noexcept.

Cheers,
Paavo

Juha Nieminen

unread,
Oct 23, 2016, 3:19:19 AM10/23/16
to
Öö Tiib <oot...@hot.ee> wrote:
> How did you achieve in your test that the destructor was throwing?
> Implicitly those are 'noexcept(true)' unless the class has any bases
> or members that got 'noexcept(false)' destructors.

Ah, so destructors are noexcept by default, without having to
specify it explicitly (while the opposite is true for constructors)?
That explains it.
0 new messages