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

2018-04-21 Thread Manu via Digitalmars-d-announce
On 21 April 2018 at 05:41, Atila Neves via Digitalmars-d-announce
 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
>

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?

2018-04-21 Thread 12345swordy via Digitalmars-d-announce

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?

2018-04-21 Thread Atila Neves via Digitalmars-d-announce

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