On Tue, 29 Nov 2011 19:50:10 +0100, deadalnix <deadal...@gmail.com> wrote:
Le 29/11/2011 18:08, Martin Nowak a écrit :
On Tue, 29 Nov 2011 16:46:55 +0100, deadalnix <deadal...@gmail.com>
wrote:
Notably, it's very difficult to map a C++ POD class with a default
constructor and copy constructor/assignement overload. struct doesn't
Don't want to be picky, but a struct with default constructor is not a
POD.
And yes it is not possible to map all C++ concepts to D.
OK, usage of POD was not the right term. But as matter of fact, C++
gives you 2 general direction to use structs/classes :
1/ You make your struct/class non copyable (making copy constructor and
assignement operator private for exemple), the destructor virtual and
use it as a polymorphic type. This is what D's class is supposed to do.
2/ Use that stract/class as a value type. You can do POD, but also
define constructor and destructor, copy constructor and overload
assignement. Anyway, you'll never be able to use proper polymorphism
here, because it would require virtual destructor at least. This is IMO,
what D's struct should achieve.
The 2/ case is overly used in almost any C++ program. And D struct
should be able to match them. It wouldn't require much to make it
working :
- Default constructor.
- The hability to define opAssign for it's own type if this(this) is
disabled.
Today we have 2 options in D : go for struct and get an error prone
binding (it's very easy to get a garbage struct, because you cannot
enforce that you'll go throw the constructor, and you cannot map copy
constructor, even with additionnal C++ code).
Or you can go final class, but you don't have a value type anymore and
it become quite hard to pass the object to/from C++, because of the
header of the object. If you get one from C++, you need the rewrap it in
a object on the D side, but . . . the copy constructor isn't mappable.
So you need to play ping pong between D and C++ to allocated the D
object, then go back to C++ to copy the data using the proper copy code,
and then go back to D to do something with that. Plus you need an heap
allocation (which isn't inexpansive ATM, because of the lock in it, and
cannot compete with stack anyway).
The focus lays on 'interfacing' C++ not integrating it.
The interfacing of C/C++ structs is limited to compatible memory layout.
It might seem arbitrary restrictive, but from what you describe
you could directly use a shared_ptr<T> in D code. This is likely too
much, as it conflicts with the semantic differences you observe.
As you have to redeclare a POD anyhow you could make it a two face
structure,
i.e. implementing some methods on both sides which might also gives you
more efficient code.
P.S.:
There is also a bug of passing struct values for x86_64.
http://d.puremagic.com/issues/show_bug.cgi?id=5570
allow for default constructor and copy constructor isn't mappable
using posblit. final class imply an overhead, and are references types
(so cannot be passed by value).
References only cost you an allocation, the call overhead is practically
inexistent
(I'm not aware of any language that achieves this).
I've recently posted a feasible solution to allocate C++ classes using
the
D garbage collector and profit from automatic lifetime management.
https://gist.github.com/1391734
Given that all bugs get sorted out, one can expect three mechanisms to
work.
- Calling free C++ functions and probably non-virtual methods
- Pass POD data forth and back
- Call virtual methods of classes with known vtable layout
Some more things as calling namespace function or certain templates
could
probably be provided by a library. But it should suffice to provide zero
overhead
interfacing to most C++ code.
Interfacing QT with it's heavy use of virtual calls,
multiple-inheritance
and a custom pre-processor will require an additional simplifying
wrapper layer
on the C++ side.
martin
I did had a look at that code just befor you posted (somebody mention
that on irc). This is a nice piece of code. But clearly solve another
problem that the one I'm talking about.
If your are interested I wrote something about starting thread on the
C++ side but remaining compatible with D (so you can call D code from
the C++ thread) here :
http://www.deadalnix.42/2011/11/24/interfacing-d-with-c-start-new-thread/
(require 42registry).