extern(C++) and struct (constness mangling problem ?)
dawg at dawgfoto.de
Tue Nov 29 11:28:36 PST 2011
On Tue, 29 Nov 2011 19:50:10 +0100, deadalnix <deadalnix at gmail.com> wrote:
> Le 29/11/2011 18:08, Martin Nowak a écrit :
>> On Tue, 29 Nov 2011 16:46:55 +0100, deadalnix <deadalnix at gmail.com>
>>> 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
>> 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
> 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
i.e. implementing some methods on both sides which might also gives you
more efficient code.
There is also a bug of passing struct values for x86_64.
>>> 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
>> (I'm not aware of any language that achieves this).
>> I've recently posted a feasible solution to allocate C++ classes using
>> D garbage collector and profit from automatic lifetime management.
>> Given that all bugs get sorted out, one can expect three mechanisms to
>> - 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
>> probably be provided by a library. But it should suffice to provide zero
>> interfacing to most C++ code.
>> Interfacing QT with it's heavy use of virtual calls,
>> and a custom pre-processor will require an additional simplifying
>> wrapper layer
>> on the C++ side.
> 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 :
> (require 42registry).
More information about the Digitalmars-d