Potential strategy for avoiding problems with copy of a struct (maybe??)

jfondren julian.fondren at gmail.com
Sun Aug 22 13:37:50 UTC 2021


On Sunday, 22 August 2021 at 13:03:20 UTC, james.p.leblanc wrote:
> On Sunday, 22 August 2021 at 11:10:33 UTC, jfondren wrote:
>> On Sunday, 22 August 2021 at 07:58:12 UTC, james.p.leblanc 
>> wrote:
>>> Hello,
>>>
>> If you don't get an answer that you like, I suggesting posting 
>> functional code and then stating your dissastisfactions with 
>> it.
>
> Mattias, jfondren,
>
> Thanks both for your replies, I always learn something from 
> them.
>
> I've trimmed my code to a minimal example to give a better idea
> of my thinking on this.

I still really don't get what you're trying to do, to the point 
of wanting to know: are you making 'myadd' a field for this 
struct only so that you can check it against the address of the 
variable? Or is it a real example of data you want to protect 
from accidental copies that just, coincidentally, can also be 
used to check if the struct has been copied? And, still, are you 
sure that you want a struct and not a class?

The idea of not polluting the original of a struct requires some 
reference types as members of the struct, or a pointer, as 
otherwise everything is copied and the original is perfectly 
'protected' anyway.

Here's a struct that
1. has an int* as an example of data that shouldn't be copied, 
for example because it would result in a double free on 
destruction
2. protects against bad copies, not by forbidding copies, but by 
nulling the int* with a postblit
3. can then report that it's an original vs. a copy by seeing if 
the int* is null

```d
import std.stdio;
import core.memory : pureMalloc, pureFree;

struct Foo {
     int a, b, c;
     int* unique;

     this(int a, int b, int c) {
         this.a = a;
         this.b = b;
         this.c = c;
         unique = cast(int*) pureMalloc(int.sizeof);
         *unique = a * b * c;
     }

     void report() const {
         if (unique)
             writeln("I'm the original: ", *unique);
         else
             writeln("I am an incomplete copy :(");
     }

     this(this) {
         unique = null;
     }

     ~this() {
         pureFree(unique);
     }
}

void alwaysGetsACopy(Foo f) {
     assert(f.unique is null);
}

void reportIfOriginal(ref Foo f) {
     if (f.unique !is null)
         f.report;
}

void main() {
     auto x = Foo(1, 2, 3);
     auto y = x;

     x.report; // I'm an original
     y.report; // I'm a copy
     x.alwaysGetsACopy; // assertion succeeds
     x.reportIfOriginal; // I'm an original
     y.reportIfOriginal;
}
```


More information about the Digitalmars-d-learn mailing list