Re: Who says we can't call C++ constructors?
On 21 April 2018 at 05:41, Atila Neves via Digitalmars-d-announcewrote: > 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 > > 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 (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 (data); > } > > int Struct::number() const { > return data == nullptr ? 0 : *reinterpret_cast (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 > Paste the pre-processed D code? Did you generate the C++ mangled symbol name and call it from a D wrapper? I've attempted that before in 'normal' D ;)
Re: Who says we can't call C++ constructors?
On Saturday, 21 April 2018 at 12:41:02 UTC, Atila Neves wrote: 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 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(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 (data); } int Struct::number() const { return data == nullptr ? 0 : *reinterpret_cast (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 You are a mad man!
Who says we can't call C++ constructors?
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 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(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 (data); } int Struct::number() const { return data == nullptr ? 0 : *reinterpret_cast (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