Constructor initializer list is not calling copy constructor

  • A+

So I was learning about constructor initializer list and I wrote the following code :

class Mango {   public:    Mango(){cout<<"Mango::ctor()";}   Mango(const Mango& other){cout<<"Mango::copy_ctor()";} };  class Box {     public:      Box() : mango(Mango()) //**doesn't call copy constructor**     {     }      Mango mango; };  int main() {   Box box;      return 0; } 

I used g++ compiler for this. Its calling the constructor not copy constructor. It should call copy constructor right because I am creating an object to create another object? What's the issue here and what does standard says about it?


Because of copy elision, the copy-construction is omitted here. This behavior is guaranteed from C++17. Before C++17 it's not mandatory; the compilers are permitted, but not required to perform copy elision1.

Under the following circumstances, the compilers are required to omit the copy- and move- construction of class objects even if the copy/move constructor and the destructor have observable side-effects. They need not be present or accessible, as the language rules ensure that no copy/move operation takes place, even conceptually:

  • In initialization, if the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, the initializer expression is used to initialize the destination object:

    T x = T(T(T())); // only one call to default constructor of T, to initialize x 

That means, mango will initialized by the default constructor directly.

[1] In fact most implementations would also perform copy elision before C++17. With Gcc you can try with -fno-elide-constructors option in pre-C++17 mode to disable copy elision.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: