On Monday, 13 December 2021 at 16:29:12 UTC, Tim wrote:
I made a pull request, which changes the mangling to tail const for classes passed directly as parameter or return type, but now think this would break too much code: https://github.com/dlang/dmd/pull/13369 The proposal to add a deref-type-constructor, would also allow to have tail const classes.

A 'deref' keyword sounds interesting. I'm not an expert on compilers, but thinking about this a bit more, to me it looks like the fundamental problem is, that D tries to apply its class pointer/reference semantics to C++, even though it could do this differently. 'Deref' would only solve one (common) issue. However, in C++ it is also very common to treat classes as value types. Maybe one could give such a hint to the D compiler instead.

If I have this C++ code:
```cpp
class A { ... };

void AsValue(A value);
void AsPtr(A* value);
void AsConstPtr(const A* value);
void AsRef(A& value);
void AsConstRef(const A& value);
```

Afaik today I can really only bind to functions of the form 'AsPtr' and 'AsConstPtr'. And if I declare A in D as a struct, I could also bind to all the others, but as mentioned above that's not always possible.

How about in D I could declare that A should be used like a value type to pass it to a function, using the 'struct' keyword:

```cpp
extern(C++) class A { ... }
extern(C++) void AsValue(struct A value);
extern(C++) void AsPtr(A value); // could stay as previously, OR
extern(C++) void AsPtr(struct A* value); // same as above
extern(C++) void AsConstPtr(const(A) value);
extern(C++) void AsConstPtr(const(struct A*) value); // same as above
extern(C++) void AsRef(ref struct A value);
extern(C++) void AsConstRef(const(ref struct A) value); // same as above
```

So here the 'struct' keyword would tell the compiler to treat A like a value type, just as in C++ and thus apply pointer, const and reference semantics like in C++. Additionally, if a pure 'struct A' is encountered, the compiler would need to create a copy of the object on the stack, just as it would do for structs, to pass it to C++ (which might modify the temporary). I guess this would be trickier to implement but then you would be able to pass classes to C++ under all circumstances.

The added benefit would be, that this shouldn't change existing behavior and thus not break anything.

Unfortunately I have neither the time nor expertise to change DMD myself.

Reply via email to