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