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

Manu turkeyman at gmail.com
Sat Apr 21 18:11:09 UTC 2018


On 21 April 2018 at 05:41, Atila Neves via Digitalmars-d-announce
<digitalmars-d-announce at puremagic.com> 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 <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
>

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 ;)


More information about the Digitalmars-d-announce mailing list