On Saturday, 14 August 2021 at 20:50:47 UTC, Carl Sturtivant wrote:
```
struct S {
  int x = 1234;
}

void main() {
  import std.stdio;
   S s;
   //construction of a using &(s.x)
   auto a = Ref!(int)(&s.x);
   writeln(a); //displays 1234
   s.x += 1;
   writeln(a); //displays 1235
   a += 1;
   writeln(s.x); //displays 1236
}

struct Ref(T) {
  T* ptr;
  this(T* p) { ptr = p; }
  string toString() { import std.conv; return to!string(*ptr); }
  ref T var() { return *ptr; }
  alias var this;
}
```

Hi,

This is exactly the behaviour I was trying to obtain.

It however comes with a fair amount of overhead, as can be seen in the following llvm ir:

    define i32 @_Dmain({ i64, { i64, i8* }* } %unnamed) #0 {
%s = alloca %onlineapp.S, align 4 ; [#uses = 4, size/byte = 4] %a = alloca %"onlineapp.Ref!int.Ref", align 8 ; [#uses = 5, size/byte = 8] %1 = bitcast %onlineapp.S* %s to i8* ; [#uses = 1] call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 %1, i8* align 1 bitcast (%onlineapp.S* @onlineapp.S.__init to i8*), i64 4, i1 false) %2 = bitcast %"onlineapp.Ref!int.Ref"* %a to i8* ; [#uses = 1] call void @llvm.memset.p0i8.i64(i8* align 1 %2, i8 0, i64 8, i1 false) %3 = getelementptr inbounds %onlineapp.S, %onlineapp.S* %s, i32 0, i32 0 ; [#uses = 1, type = i32*] %4 = call %"onlineapp.Ref!int.Ref"* @pure nothrow ref @nogc @safe onlineapp.Ref!(int).Ref onlineapp.Ref!(int).Ref.__ctor(int*)(%"onlineapp.Ref!int.Ref"* nonnull returned %a, i32* %3) #4 ; [#uses = 0] %5 = load %"onlineapp.Ref!int.Ref", %"onlineapp.Ref!int.Ref"* %a, align 8 ; [#uses = 1] call void @@safe void std.stdio.writeln!(onlineapp.Ref!(int).Ref).writeln(onlineapp.Ref!(int).Ref)(%"onlineapp.Ref!int.Ref" %5) #4 %6 = getelementptr inbounds %onlineapp.S, %onlineapp.S* %s, i32 0, i32 0 ; [#uses = 2, type = i32*] %7 = load i32, i32* %6, align 4 ; [#uses = 1] %8 = add i32 %7, 1 ; [#uses = 1]
      store i32 %8, i32* %6, align 4
%9 = load %"onlineapp.Ref!int.Ref", %"onlineapp.Ref!int.Ref"* %a, align 8 ; [#uses = 1] call void @@safe void std.stdio.writeln!(onlineapp.Ref!(int).Ref).writeln(onlineapp.Ref!(int).Ref)(%"onlineapp.Ref!int.Ref" %9) #4 %10 = call i32* @pure nothrow ref @nogc @safe int onlineapp.Ref!(int).Ref.var()(%"onlineapp.Ref!int.Ref"* nonnull %a) #4 ; [#uses = 2] %11 = load i32, i32* %10, align 4 ; [#uses = 1] %12 = add i32 %11, 1 ; [#uses = 1]
      store i32 %12, i32* %10, align 4
%13 = getelementptr inbounds %onlineapp.S, %onlineapp.S* %s, i32 0, i32 0 ; [#uses = 1, type = i32*] %14 = load i32, i32* %13, align 4 ; [#uses = 1] call void @@safe void std.stdio.writeln!(int).writeln(int)(i32 %14) #4
      ret i32 0
    }

Reply via email to