How to pass a class by (const) reference to C++
Jan
Jan at Krassnigg.de
Mon Dec 13 19:06:06 UTC 2021
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.
More information about the Digitalmars-d-learn
mailing list