extern(C++) and struct (constness mangling problem ?)

deadalnix deadalnix at gmail.com
Tue Nov 29 10:50:10 PST 2011


Le 29/11/2011 18:08, Martin Nowak a écrit :
> On Tue, 29 Nov 2011 16:46:55 +0100, deadalnix <deadalnix at 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).

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


More information about the Digitalmars-d mailing list