On 5/21/2018 2:41 PM, Steven Schveighoffer wrote: > On 5/21/18 5:23 PM, Walter Bright wrote: >> In C, the way to do PIMPL is to write just a struct declaration: >> >> === s.h === >> struct S; >> >> === s.c === >> >> struct S { ... }; >> >> === t.c === >> >> struct T { >> S* pimpl; >> }; >> >> And the users of T cannot access anything in S. The straightforward equivalent in D is: >> >> === s.di === >> struct S; >> >> === s.d === >> struct S { ... } >> >> === t.d === >> import s; >> struct T { >> S* pimpl; >> }; >> >> >> But if you don't want to use .di files, such as when compiling all the files together with one command, then things get a bit awkward. D doesn't like: >> >> === s.d === >> public struct S; >> private struct S { ... } >> >> Making a public alias to a private struct doesn't work, as the struct's members are still accessible. I finally found a way: >> >> === s.d === >> public struct Spimpl { >> private S* pimpl; >> private alias pimpl this; >> } >> private struct S { ... } >> >> === t.d === >> import s; >> struct T { >> Spimpl* s; In C, the way to do PIMPL is to write just a struct declaration:=== s.h ===struct S;=== s.c === #include "s.h"struct S { ... };=== t.c === #include "s.h"struct T {S* pimpl;};And the users of T cannot access anything in S. The straightforward equivalent in D is:=== s.di ===struct S;=== s.d ===struct S { ... }=== t.d ===import s;struct T {S* pimpl;};But if you don't want to use .di files, such as when compiling all the files together with one command, then things get a bit awkward. D doesn't like:=== s.d ===public struct S;private struct S { ... }Making a public alias to a private struct doesn't work, as the struct's members are still accessible. I finally found a way:=== s.d ===public struct Spimpl {private S* pimpl;private alias pimpl this;private struct S { ... }=== t.d ===import s;struct T {Spimpl* s; > > Don't you mean a nonpointer here? On 5/21/18 5:23 PM, Walter Bright wrote:Don't you mean a nonpointer here? >> } >> >> and the contents of S are inaccessible to T, while type safety is maintained. There are no extra indirections - the alias this takes care of that. s.d can use s to directly access S's contents, but t.d cannot. >> >> https:// github.com/ dlang/dmd/ blob/ma ster/src/ dmd/func. d#L229 >> https:// github.com/ dlang/dmd/ blob/ master/ src/dmd/ dinterpret. d#L151 >> >> C: >> C++: and the contents of S are inaccessible to T, while type safety is maintained. There are no extra indirections - the alias this takes care of that. s.d can use s to directly access S's contents, but t.d cannot.C: http://wiki.c2.com/?PimplIdiom C++: http:// en.cppref erence.com/ w/cpp/ language/pimpl > > > Will this really work? > > I mean, if the compiler can see the implementation of S, even though it's private, can't it inline things and screw with the binary compatibility? Will this really work?I mean, if the compiler can see the implementation of S, even though it's private, can't it inline things and screw with the binary compatibility? > I thought that was the main benefit of pimpl, to create a barrier which you know is going to separate the user from the implementation. In this case, I was looking to hide it from the user.