Who says we can't call C++ constructors?

Atila Neves atila.neves at gmail.com
Sat Apr 21 12:41:02 UTC 2018


 From https://dlang.org/spec/cpp_interface.html:

"C++ constructors, copy constructors, move constructors and 
destructors cannot be called directly in D code".

O RLY?

     // hdr.hpp
     struct Struct {
         void *data;
         Struct(int i);
         Struct(const Struct&);
         Struct(Struct&&);
         ~Struct();
         int number() const;
     };


     // cpp.cpp
     #include "hdr.hpp"
     #include <iostream>

     using namespace std;

     Struct::Struct(int i) {
         cout << "  C++:  int ctor " << i << endl;
         data = new int(i);
     }

     Struct::Struct(const Struct& other) {
         cout << "  C++: copy ctor " << other.number() << endl;
         data = new int(*reinterpret_cast<int*>(other.data));
     }

     Struct::Struct(Struct&& other) {
         cout << "  C++: move ctor " << other.number() << endl;
         data = other.data;
         other.data = nullptr;
     }

     Struct::~Struct() {
         cout << "  C++ dtor " << number() << endl;
         delete reinterpret_cast<int*>(data);
     }

     int Struct::number() const {
         return data == nullptr ? 0 : 
*reinterpret_cast<int*>(data);
     }


     // ctors.dpp
     #include "hdr.hpp"
     import std.stdio;

     void main() {
         writeln("D: int ctor");
         const cs = const Struct(2);
         auto  ms = Struct(3);
         writeln;

         writeln("D: copy ctor");
         auto ccs = Struct(cs); assert(ccs.number() == 2);
         auto cms = Struct(ms); assert(cms.number() == 3);
         writeln;

         writeln("D: move ctor");
         auto tmp = Struct(4);
         // dpp.move causes the move ctor be called instead of the 
copy ctor
         auto mv1 = Struct(dpp.move(tmp)); assert(mv1.number() == 
4);
         // moved from, now T.init (even if the C++ code doesn't 
do that)
         assert(tmp.data is null);

         // This last line doesn't work with dmd due to issue 
18784.
         // It works fine with ldc though.
         auto mv2 = Struct(Struct(5)); assert(mv2.number() == 5);
         writeln;
     }


% clang++ -c cpp.cpp
% d++ --compiler=ldc2 ctors.dpp cpp.o -L-lstdc++
% ./ctors

D: int ctor
   C++:  int ctor 2
   C++:  int ctor 3

D: copy ctor
   C++: copy ctor 2
   C++: copy ctor 3

D: move ctor
   C++:  int ctor 4
   C++: move ctor 4
   C++ dtor 0
   C++:  int ctor 5
   C++: move ctor 5
   C++ dtor 0

   C++ dtor 5
   C++ dtor 4
   C++ dtor 0
   C++ dtor 3
   C++ dtor 2
   C++ dtor 3
   C++ dtor 2



Atila



More information about the Digitalmars-d-announce mailing list