Date: Fri, 7 Aug 2020 17:46:56 +0000 (UTC)
On Thursday, August 6, 2020, 5:48:52 PM CDT, Ville Voutilainen <ville.voutilainen_at_[hidden]> wrote:
On Fri, 7 Aug 2020 at 01:36, Walt Karas via Std-Proposals
<std-proposals_at_[hidden]> wrote:
> > WK: Good point, they should be noexcept if the corresponding constructor is noexcept (and the destructor).
> And if it isn't noexcept, what do you do?
> WK: Under the current Standard, if a base or member assignment op is noexcept(false), isn't the default assignment op noexect(false)? That is what I'm thinking, noexcept is inferred for the default.
That's not the point. Look:
C & operator = (C const &rhs)
{
if (this != &rhs)
{
this->~C(); // #1, now the object is dead
::new (this) C(rhs); // #2, if this throws, it stays dead
}
return *this;
}
void some_automatic_scope() {
C c1;
C c2;
c1 = c2; // if #2 threw, your program is now dead (because there
will be an attempt to destroy c1, and it's already dead), and there's
no recovery from that.
}
You can't do a destroy+placement-new if the placement-new can throw.
WK: OK, also good point. If the constructor can throw, then conceptually the default assign can be like this: https://godbolt.org/z/jvdf53
But then the existence of a default copy assign would be dependent on the existence of both the copy and move constructor. And, this is a lot of overhead.
Go read Sutter's Exceptional C++
and More Exceptional C++, and try again.
On Fri, 7 Aug 2020 at 01:36, Walt Karas via Std-Proposals
<std-proposals_at_[hidden]> wrote:
> > WK: Good point, they should be noexcept if the corresponding constructor is noexcept (and the destructor).
> And if it isn't noexcept, what do you do?
> WK: Under the current Standard, if a base or member assignment op is noexcept(false), isn't the default assignment op noexect(false)? That is what I'm thinking, noexcept is inferred for the default.
That's not the point. Look:
C & operator = (C const &rhs)
{
if (this != &rhs)
{
this->~C(); // #1, now the object is dead
::new (this) C(rhs); // #2, if this throws, it stays dead
}
return *this;
}
void some_automatic_scope() {
C c1;
C c2;
c1 = c2; // if #2 threw, your program is now dead (because there
will be an attempt to destroy c1, and it's already dead), and there's
no recovery from that.
}
You can't do a destroy+placement-new if the placement-new can throw.
WK: OK, also good point. If the constructor can throw, then conceptually the default assign can be like this: https://godbolt.org/z/jvdf53
But then the existence of a default copy assign would be dependent on the existence of both the copy and move constructor. And, this is a lot of overhead.
Go read Sutter's Exceptional C++
and More Exceptional C++, and try again.
Received on 2020-08-07 12:50:22