简体   繁体   中英

Compiler generated noexcept ctor for class with members constructed with no such guarantee

Consider an example:

class ClassThatMayThrowInCtor
{
     ClassThatMayThrowInCtor()
     {
          if (g_unlucky) throw "Exception";
     }
};

class Aggregate
{
     ClassThatMayThrowInCtor m_member;
};

As far as my limited knowledge goes, compiler may in some circumstances in C++14 generate a default ctor that is noexcept .

Will it in this case, or will it understand that since member's default ctor does not provide any such guarantee, it should not either?


Asked for reference of the above claim ( in some circumstances... ), I've failed to find it within the standard, but Andrzej's blog does mention:

This does not mean that noexcept is useless. Compiler will annotate implicitly generated member functions of your classes (constructors, copy and move assignments and destructor) with noexcept , as appropriate, and STL components will be querying for this annotation. The feature will enable significant optimizations (by using move constructors) even though you will not see a single noexcept keyword. And when compiler annotates functions with noexcept it does it correctly (except for destructors), so there is no risk that some noexcept move constructor will throw.

(emphasis mine)

From [except.spec] :

14 - [...] If f is [...] an implicitly declared default constructor [...] f allows all exceptions if any function it directly invokes allows all exceptions, and f has the exception-specification noexcept(true) if every function it directly invokes allows no exceptions. [...]

The implicitly declared default constructor of Aggregate directly invokes ClassThatMayThrowInCtor::ClassThatMayThrowInCtor() which allows all exceptions, so Aggregate::Aggregate() allows all exceptions and is not noexcept .

You can check this at compile time. B's default constructor is not noexcept in the program below:

struct A {
    A() {
        throw 0;
    }
};

struct B {
    A a;
};

static_assert(noexcept(B{}), "");

int main() {
    return 0;   
}

This program fails to compile, because the static_assert fails.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM