www.digitalmars.com         C & C++   DMDScript  

digitalmars.dip.ideas - By-ref opaque structs

reply Richard (Rikki) Andrew Cattermole <richard cattermole.co.nz> writes:
Opaque structs are typically used as pointers.

```d
struct Context;

extern(C) void doSomething(Context*);
```

However they can be useful for payloads in D with dynamically 
sized structs.

```d
struct Payload;

struct Node {
     Node* next;
     Payload[0] payload;
}

void walk(Node* node) {
     Payload* payload = &node.payload[0];
}
```

So let's make this a little easier on ourselves, and make opaque 
structs always by-ref if it is were otherwise by-value (and then 
error) and allow them to be the last field of a struct.

```d
struct Node {
     Node* next;
     Payload payload;
}

void view(Payload payload) {
     Payload* payload2 = &payload;
}
```

This has a nice usage in sumtypes:

```d
struct None;

__sumtype(None) sumtype;
sumtype.match((a) => 2);
```

As it means we don't have to link against or use random None's 
all over codebases that are not linking against druntime, but we 
can still define it in object.d
Jul 29
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Thursday, 30 July 2026 at 01:18:26 UTC, Richard (Rikki) Andrew 
Cattermole wrote:
 So let's make this a little easier on ourselves, and make 
 opaque structs always by-ref if it is were otherwise by-value 
 (and then error) and allow them to be the last field of a 
 struct.

 ```d
 struct Node {
     Node* next;
     Payload payload;
 }

 void view(Payload payload) {
     Payload* payload2 = &payload;
 }
 ```
Why not simply use `Payload[0]` and `ref Payload payload` to clearly communicate to the reader what the code is doing? I don't see the benefit of adding a special case here.
Sep 01
parent Atila Neves <atila.neves gmail.com> writes:
On Tuesday, 1 September 2026 at 20:30:13 UTC, Paul Backus wrote:
 On Thursday, 30 July 2026 at 01:18:26 UTC, Richard (Rikki) 
 Andrew Cattermole wrote:
 So let's make this a little easier on ourselves, and make 
 opaque structs always by-ref if it is were otherwise by-value 
 (and then error) and allow them to be the last field of a 
 struct.

 ```d
 struct Node {
     Node* next;
     Payload payload;
 }

 void view(Payload payload) {
     Payload* payload2 = &payload;
 }
 ```
Why not simply use `Payload[0]` and `ref Payload payload` to clearly communicate to the reader what the code is doing? I don't see the benefit of adding a special case here.
This.
Oct 12
prev sibling next sibling parent Ogion <ogion.art gmail.com> writes:
On Thursday, 30 July 2026 at 01:18:26 UTC, Richard (Rikki) Andrew 
Cattermole wrote:
 This has a nice usage in sumtypes:

 ```d
 struct None;

 __sumtype(None) sumtype;
 sumtype.match((a) => 2);
 ```

 As it means we don't have to link against or use random None's 
 all over codebases that are not linking against druntime, but 
 we can still define it in object.d
I use `typeof(null)` exactly for this: ```D SumType!(typeof(null)) sumtype; writeln(sumtype.match!((s) => 42)); ```
Sep 06
prev sibling parent Quirin Schroll <qs.il.paperinik gmail.com> writes:
On Thursday, 30 July 2026 at 01:18:26 UTC, Richard (Rikki) Andrew 
Cattermole wrote:
 Opaque structs are typically used as pointers.

 ```d
 struct Context;

 extern(C) void doSomething(Context*);
 ```

 However they can be useful for payloads in D with dynamically 
 sized structs.

 ```d
 struct Payload;

 struct Node {
     Node* next;
     Payload[0] payload;
 }

 void walk(Node* node) {
     Payload* payload = &node.payload[0];
 }
 ```
If anything, we should make the practice of using a 0-size array obsolete and use an attribute or some other indicator for such a dynamically sized payload array. Indexing a 0-size array just looks wrong. Ideally, it would be something like `Payload[?]`.
Sep 23