[GSoC] Header Generation for C/C++

Manu turkeyman at gmail.com
Thu Sep 5 21:43:14 UTC 2019


On Thu, Sep 5, 2019 at 5:01 AM Eduard Staniloiu via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
>
> > On Thursday, 5 September 2019 at 11:25:47 UTC, Eduard Staniloiu
> > wrote:
> > [...]
> > I'm currently working on correctly generating the ctors and
> > dtors declarations.
>
> More details about the above.
>
> When I began working on the project, the code was generating two
> ctors for each `struct`
>    1. a default ctor that was initializing all the struct fields
> with their default value
>    2. a ctor that took all the struct field types as arguments and
> assigned the supplied arguments to each struct field (Ex.
> `this->x = x`).
>
> The above two replicate (almost) the D behavior of constructing a
> struct that has no ctor defined. I say almost because you can
> either use the default ctor, or you **must** pass all the field
> arguments to the ctor (in D you can pass as many as you want, not
> all).
>
> When I first saw this and ran it with Razvan and Andrei and we
> said "Thats odd. The tool should only generate declarations, not
> definitions". I asked Iain about it and he said he couldn't
> remember why it was there, but probably he needed it at some
> point. So, in the light of this, we took the decision of dropping
> the ctor definition generation until further notice.
>
> Well, this week I had an epiphany: for any struct, we have to
> generate the default ctor definition because on the D side,
> fields are default initialized to their `.init` value. If one
> would construct a struct (Ex. on the stack) on the C++ side, then
> the code could break.
>
> Let's see the following simple struct example
> ```
> // D module
>
> extern (C++) struct S
> {
>    int* ptr;
>    void apiFun() {
>      if (ptr) {
>        /* do stuff */
>      }
>    }
> }
>
> void bar()
> {
>    S s;
>    s.apiFun();
> }
>
> // C++ code
>
> // Generated struct header
> struct S
> {
>    int* ptr;
>    void apiFun();
> };
>
> void gun()
> {
>    S s;
>    s.apiFun();
> }
> ```
>
> The `bar` function, being on the D side, is fine.
> The `gun` function on the other hand, will be UB.
>
> This is bad.
>
> Starting from this, I came to the following conclusions:
>    - For any `extern (C++)` struct, a default ctor must be
> generated

We have discussed responding to the C++ language version before, and
for >= C++11 it would be nice to use member initialisers rather than a
default ctor.

>    - If a struct defines a dtor, a declaration must be generated:
> `virtual ~A();`

Not virtual though right?

>    - For any defined ctors, a declaration must be generated

A constructor is no different than any other method. I expect you're
emiting all the methods right?

> I think that if a struct defines a copy ctor, an opAssign, then
> an equivalent C++ declaration must be generated.

These are just normal methods too... if a method has a C++
counterpart, then emit a declaration for it. This includes all
constructors (except postblit, that guy's a problem).
You could translate operators (perhaps as a stretch goal), ie;
opAssign -> operator=

> What do you think, folks?

I think declarations for all methods that have a valid C++ counterpart
should be emit... no?


On a tangent, can you confirm where you landed with respect to the
enum discussion? I want to be sure we landed in a satisfying place.
Did you go with the fully-loaded macro solution, so the client can
define the macro's to taste?


More information about the Digitalmars-d mailing list