Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pimpl-idiom in the D programming language

Tags:

pimpl-idiom

d

D has a fantastic module system which reduces compilation times dramatically compared to C++. According to the documentation D still provides opaque structs and unions in order to enable the pimpl idiom. My question is: How can I declare a nested struct (or union) in one module and define it in another one? What is the syntax for that?

In C++ the header would look like this

struct S { 
    ... 
    struct Impl; 
    Impl * p; 
};

and the implementation file (cpp-file) would use some interesting-looking ::-syntax like this:

#include "header.h"
struct S::Impl { 
    ... 
};

How do I implement the same in D?

like image 231
Ralph Tandetzky Avatar asked Mar 22 '23 09:03

Ralph Tandetzky


2 Answers

D (DMD, at least) uses .di files for declarations. They are somewhat equivalent to C .h files, however they are optional. The D compiler can generate .di files automatically (when the -H switch is specified), although I believe that currently all it does is strip function bodies and unittests.

Here's one way to achieve PImpl using .di files:

  • mod.di:

    struct S
    {
        struct I;
        I* pi;
    }
    
  • mod.d:

    struct S
    {
        struct I
        {
            int v;
        }
    
        I* pi;
    }
    

Note that it is currently your responsibility to make sure that the fields in S are the same in both the .d and .di file - if they differ, the compiled modules will have differing knowledge of how the fields are laid out, which can lead to memory corruption. The current compiler implementations do not verify if definitions match in .d and .di files.

like image 89
Vladimir Panteleev Avatar answered Mar 28 '23 18:03

Vladimir Panteleev


My question is: How can I declare a nested struct (or union) in one module and define it in another one?

To get it straight - it is intentionally impossible in D by design. It is a direct consequence of having a reliable module system - every symbol declaration is implicitly qualified by a module name it is declared inside. And for variety of reasons you can't hijack a symbol into another modules "namespace".

That said, it is not necessary to do it in same module to use pimpl approach. You can refer to CyberShadow answer for more details.

like image 33
Mihails Strasuns Avatar answered Mar 28 '23 19:03

Mihails Strasuns