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, truein gcc 4.7.And the bug is not that the generated move constructors aren’t noexcept, but that
std::moveis not marked asnoexcept, as we can see with the additional tests: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
noexceptif all functions it will need to call are allnoexcept.