I recently started to add the new noexcept
specification to move constructors/assignments wherever possible. Now I started to wonder what the exception specification of implicit generated member functions looks like. Since having noexcept
move functions allows the use of more efficient code paths(e.g. when resizing a vector
) I would hope that those are declared as noexcept whenever possible. I had problems understanding what the standard has to say about that and therefore tried the following code in g++4.6 (with -std=c++0x
) to get some grip on it:
struct foobar{};
int main()
{
foobar a, b;
std::cout<<std::boolalpha
<<noexcept(foobar())<<", "<<noexcept(foobar(a))<<", "
<<noexcept(a = b) <<", "<<noexcept(a = std::move(b))<<", "
<<noexcept(foobar(std::move(a)))<<std::endl;
}
This gave me an output of True, True, True, False, False
, meaning that default and copy constructor/assignment where noexcept
, while move operation where not.
Now for my question:
Under what circumstances are implicit generated (or defaulted) member functions declared as noexcept
? Furthermore is the obseved behaviour for foobar
correct or simply a compiler bug in gcc4.6?
Library bug — it shows true, true, true, true, true
in gcc 4.7.
And the bug is not that the generated move constructors aren't noexcept, but that std::move
is not marked as noexcept
, as we can see with the additional tests:
std::cout << noexcept(a = static_cast<foobar&&>(b)) << ", " // true
<< noexcept(foobar(static_cast<foobar&&>(b))) << ", " // true
<< noexcept(std::move(b)) << std::endl; // false
Most of the library functions in gcc 4.6 was not noexcept-correct, and this has been addressed in gcc 4.7,
As for when the implcitely generated member functions are noexcept, this is documented in §15.4/14. Basically, it is noexcept
if all functions it will need to call are all noexcept
.
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-idT
if and only ifT
is allowed by the exception-specification of a function directly invoked byf
’s implicit definition;f
shall allow all exceptions if any function it directly invokes allows all exceptions, andf
shall allow no exceptions if every function it directly invokes allows no exceptions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With