View mode: basic / threaded / horizontal-split · Log in · Help
January 19, 2012
C++ pimpl
Qt for example uses the pimpl idiom for achieving ABI compatibility between releases. The problem is additional heap allocations, additional indirection and you pay for it, whether needed or not. (For example even derived classes in the same library pay for it.)
I wondered whether this would still be necessary in D and I think not.
In D, as interface files are automatically generated, it could be possible to have ones created with let's say a special "@private_impl" property or something. For these classes the object size would have to be stored as hidden static member in the library. The new operator could then simply read the size and allocate the needed space. Derived class methods can also use the size to calculate the offset of the derived class data members.

So you would lose some optimizations, e.g. initializing of base members can't be inlined and stuff. But this is not possible with pimpl either and you gain the following:
- You only pay for it if you want it. You can also use the standard .di file and lose the ABI compatiblity between versions if you so want and derived classes in the same library do not need to pay any additional overhead either.
- It is completely transparent: If you later on decide you need ABI compatibility between releases, it's just a matter of a compiler switch and differend .di files.
- I think it will also be more efficient than pimpl in all regards.

I think this would be a real neat and very important feature, when it comes to shared libraries. Is there any plan to implement something like that in the future? Do I miss something?

Best regards,

Robert
-- 
"Feel free" - 10 GB Mailbox, 100 FreeSMS/Monat ...
Jetzt GMX TopMail testen: http://www.gmx.net/de/go/topmail
January 20, 2012
Re: C++ pimpl
On 1/19/2012 12:48 PM, Roberto Caravani wrote:
> I think this would be a real neat and very important feature, when it comes
> to shared libraries. Is there any plan to implement something like that in
> the future? Do I miss something?


The pimpl pros and cons are the same for C++ and D.
January 20, 2012
Re: C++ pimpl
First of all thanks for this fast answer!

> On 1/19/2012 12:48 PM, Roberto Caravani wrote:
> > I think this would be a real neat and very important feature, when it
> > comes to shared libraries. Is there any plan to implement something
> > like that in the future? Do I miss something?
> 
> The pimpl pros and cons are the same for C++ and D.

Well, yes they are currently. But as D has pure reference semantics for 
classes, it would be easier to handle the case when the size of an object is 
not known at compile time. It basically comes down to having operator new read 
the size from the library and having derived classes members do some offset 
calculation. (Member initialization would have to be done by a function) Is 
there something missing?

Is there a flaw in my proposal? Isn't it worth the effort? What are the 
problems?

In Java pimpl for ABI compatibility seems not to be neccessary, according to:
http://java.sun.com/docs/books/jls/second_edition/html/binaryComp.doc.html
(It states that you can freely add and remove private fields)
but ok, Java is not a system programming language, they might cheat somehow.

Such a feature seems really cool to me, especially for library developers, 
because they have to care less that they are implementing a dynamic library. 
And you can easily avoid the costs if you don't need it, no rewrite necessary, 
just a recompilation of the program. (Not even the library, if you don't care 
about the hidden static size member and the initialization methods)

Maybe I am completely wrong, but if so I want to know 

This is not really a feature request, as there are far more important things 
to do at the moment. This is more a: "Is it possible?" "Would you like to have 
it, if someone else implemented it?"

Best regards,

Robert

P.S.: Another benefit I forgot to mention: For such a not exposing .di file, I 
think you can even remove all non public imports (if there are no inline 
methods), as all you need to know is the size of the object.
I know that compilation time isn't that much of an issue as with C++, but 
during development you could use such non exposing .di files, which would 
change much less often. Thus recompilation of object files due to changes in 
the di files could be decreased, shortening compile time for large projects. 
In addition the compiler does not need to see, nor evaluate non public imports 
in those di files.

What do you think?
January 20, 2012
Re: C++ pimpl
On 1/20/2012 2:12 AM, Robert Caravani wrote:
> First of all thanks for this fast answer!
>
>> On 1/19/2012 12:48 PM, Roberto Caravani wrote:
>>> I think this would be a real neat and very important feature, when it
>>> comes to shared libraries. Is there any plan to implement something
>>> like that in the future? Do I miss something?
>>
>> The pimpl pros and cons are the same for C++ and D.
>
> Well, yes they are currently. But as D has pure reference semantics for
> classes, it would be easier to handle the case when the size of an object is
> not known at compile time. It basically comes down to having operator new read
> the size from the library and having derived classes members do some offset
> calculation. (Member initialization would have to be done by a function) Is
> there something missing?
>
> Is there a flaw in my proposal? Isn't it worth the effort? What are the
> problems?
>
> In Java pimpl for ABI compatibility seems not to be neccessary, according to:
> http://java.sun.com/docs/books/jls/second_edition/html/binaryComp.doc.html
> (It states that you can freely add and remove private fields)
> but ok, Java is not a system programming language, they might cheat somehow.

Java can recompile things on the fly.


> Such a feature seems really cool to me, especially for library developers,
> because they have to care less that they are implementing a dynamic library.
> And you can easily avoid the costs if you don't need it, no rewrite necessary,
> just a recompilation of the program. (Not even the library, if you don't care
> about the hidden static size member and the initialization methods)
>
> Maybe I am completely wrong, but if so I want to know
>
> This is not really a feature request, as there are far more important things
> to do at the moment. This is more a: "Is it possible?" "Would you like to have
> it, if someone else implemented it?"

What you're asking for is dynamic typing. You can achieve something equivalent 
using opDispatch and std.variant.
January 21, 2012
Re: C++ pimpl
On Fri, 20 Jan 2012 13:13:42 -0600, Walter Bright <newshound2@digitalmars.com> wrote:

> On 1/20/2012 2:12 AM, Robert Caravani wrote:
>> First of all thanks for this fast answer!
>>
>>> On 1/19/2012 12:48 PM, Roberto Caravani wrote:
>>>> I think this would be a real neat and very important feature, when it
>>>> comes to shared libraries. Is there any plan to implement something
>>>> like that in the future? Do I miss something?
>>>
>>> The pimpl pros and cons are the same for C++ and D.
>>
>> Well, yes they are currently. But as D has pure reference semantics for
>> classes, it would be easier to handle the case when the size of an object is
>> not known at compile time. It basically comes down to having operator new read
>> the size from the library and having derived classes members do some offset
>> calculation. (Member initialization would have to be done by a function) Is
>> there something missing?
>>
>> Is there a flaw in my proposal? Isn't it worth the effort? What are the
>> problems?
>>
>> In Java pimpl for ABI compatibility seems not to be neccessary, according to:
>> http://java.sun.com/docs/books/jls/second_edition/html/binaryComp.doc.html
>> (It states that you can freely add and remove private fields)
>> but ok, Java is not a system programming language, they might cheat somehow.
>
> Java can recompile things on the fly.
>
>
>> Such a feature seems really cool to me, especially for library developers,
>> because they have to care less that they are implementing a dynamic library.
>> And you can easily avoid the costs if you don't need it, no rewrite necessary,
>> just a recompilation of the program. (Not even the library, if you don't care
>> about the hidden static size member and the initialization methods)
>>
>> Maybe I am completely wrong, but if so I want to know
>>
>> This is not really a feature request, as there are far more important things
>> to do at the moment. This is more a: "Is it possible?" "Would you like to have
>> it, if someone else implemented it?"
>
> What you're asking for is dynamic typing. You can achieve something equivalent
> using opDispatch and std.variant.
>

Is something like https://jshare.johnshopkins.edu/rjacque2/public_html/ what you're looking for?
January 22, 2012
Re: C++ pimpl
I have been asking that for some time now, i am afraid you won't get much  
of an audience.
You can get rid of both additional allocation and indirection but it is  
not pretty. We could definitely use some help/sugar on this.

http://www.artima.com/cppsource/backyard3.html

On Thu, 19 Jan 2012 22:48:39 +0200, Roberto Caravani <JFanatiker@gmx.at>  
wrote:

> Qt for example uses the pimpl idiom for achieving ABI compatibility  
> between releases. The problem is additional heap allocations, additional  
> indirection and you pay for it, whether needed or not. (For example even  
> derived classes in the same library pay for it.)
> I wondered whether this would still be necessary in D and I think not.
> In D, as interface files are automatically generated, it could be  
> possible to have ones created with let's say a special "@private_impl"  
> property or something. For these classes the object size would have to  
> be stored as hidden static member in the library. The new operator could  
> then simply read the size and allocate the needed space. Derived class  
> methods can also use the size to calculate the offset of the derived  
> class data members.
>
> So you would lose some optimizations, e.g. initializing of base members  
> can't be inlined and stuff. But this is not possible with pimpl either  
> and you gain the following:
>  - You only pay for it if you want it. You can also use the standard .di  
> file and lose the ABI compatiblity between versions if you so want and  
> derived classes in the same library do not need to pay any additional  
> overhead either.
>  - It is completely transparent: If you later on decide you need ABI  
> compatibility between releases, it's just a matter of a compiler switch  
> and differend .di files.
>  - I think it will also be more efficient than pimpl in all regards.
>
> I think this would be a real neat and very important feature, when it  
> comes to shared libraries. Is there any plan to implement something like  
> that in the future? Do I miss something?
>
> Best regards,
>
> Robert
January 23, 2012
Re: C++ pimpl
On Mon, 23 Jan 2012 01:39:23 +0200, so <so@so.so> wrote:

> I have been asking that for some time now, i am afraid you won't get  
> much of an audience.
> You can get rid of both additional allocation and indirection but it is  
> not pretty. We could definitely use some help/sugar on this.
>
> http://www.artima.com/cppsource/backyard3.html

http://www.digitalmars.com/d/archives/digitalmars/D/Implementation_hiding_139625.html

There is another issue Walter forgot to mention in the article.
I think there might be a way but looks like we also loose the "destructor".
Which means we are all the way back to the  
http://en.wikipedia.org/wiki/Opaque_pointer.

Walter, is there a way to get around destructor limitation?
January 23, 2012
Re: C++ pimpl
On Mon, 23 Jan 2012 02:07:29 +0200, so <so@so.so> wrote:

> On Mon, 23 Jan 2012 01:39:23 +0200, so <so@so.so> wrote:
>
>> I have been asking that for some time now, i am afraid you won't get  
>> much of an audience.
>> You can get rid of both additional allocation and indirection but it is  
>> not pretty. We could definitely use some help/sugar on this.
>>
>> http://www.artima.com/cppsource/backyard3.html
>
> http://www.digitalmars.com/d/archives/digitalmars/D/Implementation_hiding_139625.html
>
> There is another issue Walter forgot to mention in the article.
> I think there might be a way but looks like we also loose the  
> "destructor".
> Which means we are all the way back to the  
> http://en.wikipedia.org/wiki/Opaque_pointer.
>
> Walter, is there a way to get around destructor limitation?

1. Lose, not loose.
2. I linked the wikipedia page to point to the "C version" not the others.
I was wrong calling them taft types (it is the name of the Ada version).
January 23, 2012
Re: C++ pimpl
On 01/23/2012 01:07 AM, so wrote:
> On Mon, 23 Jan 2012 01:39:23 +0200, so <so@so.so> wrote:
>
>> I have been asking that for some time now, i am afraid you won't get
>> much of an audience.
>> You can get rid of both additional allocation and indirection but it
>> is not pretty. We could definitely use some help/sugar on this.
>>
>> http://www.artima.com/cppsource/backyard3.html
>
> http://www.digitalmars.com/d/archives/digitalmars/D/Implementation_hiding_139625.html
>
>
> There is another issue Walter forgot to mention in the article.
> I think there might be a way but looks like we also loose the "destructor".
> Which means we are all the way back to the
> http://en.wikipedia.org/wiki/Opaque_pointer.
>
> Walter, is there a way to get around destructor limitation?

This seems to work.

a.di:

final class A{
    private this();
    static A factory();
    T1 publicMember1(int x);
    T2 publicMember2(float y);
    T3 publicField;
    // ...
}

a.d:

class A{
    static A factory(){return new A;}
    T1 publicMember1(int x){ ... }
    T2 publicMember2(float y){ ... }
    T3 publicField;
    // ...
private:
    T1 field1;
    T2 field2;
}
January 23, 2012
Re: C++ pimpl
On Mon, 23 Jan 2012 02:33:47 +0200, Timon Gehr <timon.gehr@gmx.ch> wrote:

> This seems to work.
>
> a.di:
>
> final class A{
>      private this();
>      static A factory();
>      T1 publicMember1(int x);
>      T2 publicMember2(float y);
>      T3 publicField;
>      // ...
> }
>
> a.d:
>
> class A{
>      static A factory(){return new A;}
>      T1 publicMember1(int x){ ... }
>      T2 publicMember2(float y){ ... }
>      T3 publicField;
>      // ...
> private:
>      T1 field1;
>      T2 field2;
> }

Oh? How so? Within current framework it is not possible.
Probably a glitch in matrix :)
« First   ‹ Prev
1 2 3
Top | Discussion index | About this forum | D home