August 15, 2021

On Sunday, 15 August 2021 at 07:10:17 UTC, JG wrote:

>

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:

[...]

I'm not really familiar with llvm ir, but looking at it on godbolt, it seems like the main difference is that taking the address of s.x forces the compiler to place s in memory, rather than keeping it entirely in registers:

https://d.godbolt.org/z/1afbsM6fv

August 15, 2021

On Sunday, 15 August 2021 at 16:49:22 UTC, Paul Backus wrote:

>

On Sunday, 15 August 2021 at 07:10:17 UTC, JG wrote:

>

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:

[...]

I'm not really familiar with llvm ir, but looking at it on godbolt, it seems like the main difference is that taking the address of s.x forces the compiler to place s in memory, rather than keeping it entirely in registers:

https://d.godbolt.org/z/1afbsM6fv

The function std.stdio.writeln!(example.Ref!(int)) is not trivial. I doubt there is a reasonable optimization/transformation path from a call to std.stdio.writeln!(example.Ref!(int)) to a call to std.stdio.writeln!(int).writeln(int).
Without being able to simplify it to that call, s has to be put in memory. It's the opaqueness of std.stdio.writeln!(example.Ref!(int)) and that it (must) takes the address of s.x as parameter.

-Johan

August 15, 2021

On Sunday, 15 August 2021 at 07:10:17 UTC, JG wrote:

>

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:

[...]

What you are asking for are reference variables. C++ has them: the example here illustrates the behavior you want.
https://www.geeksforgeeks.org/references-in-c/

D does not have them, as mentioned above:
https://forum.dlang.org/post/mailman.2714.1628875187.3446.digitalmars-d-learn@puremagic.com

So to get the behavior you want, they have to be simulated, which is what this does:
https://forum.dlang.org/post/lcrrnszslpyazoziyicb@forum.dlang.org

Next version: no toString and storage passed in by reference rather than by pointer.

```
struct S {
  int x = 1234;
}

void main() {
  import std.stdio;
   S s;
   auto p = &s.x;
   //construction of a using &(s.x)
   auto a = Ref!(int)(*p);
   //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(ref T x) { ptr = &x; }
  @property ref T var() { return *ptr; }
  alias var this;
}
```

I see no way to avoid overhead, as I see no simpler simulation.

August 16, 2021

On Sunday, 15 August 2021 at 21:53:14 UTC, Carl Sturtivant wrote:

>

On Sunday, 15 August 2021 at 07:10:17 UTC, JG wrote:

>

[...]

What you are asking for are reference variables. C++ has them: the example here illustrates the behavior you want.
https://www.geeksforgeeks.org/references-in-c/

[...]

Thanks for the links and code. Looking at the assembly as suggested by others it seems that after optimization this not too bad.

August 17, 2021

On Monday, 16 August 2021 at 19:30:19 UTC, JG wrote:

>

On Sunday, 15 August 2021 at 21:53:14 UTC, Carl Sturtivant wrote:

>

On Sunday, 15 August 2021 at 07:10:17 UTC, JG wrote:

>

[...]

What you are asking for are reference variables. C++ has them: the example here illustrates the behavior you want.
https://www.geeksforgeeks.org/references-in-c/

[...]

Thanks for the links and code. Looking at the assembly as suggested by others it seems that after optimization this not too bad.

The problem is not optimization. The semantics of the code are different when you use the Ref!int solution versus simply int. You'll see this in template instantiations, as in the writeln example.

writeln is a template and writeln!int is something different from writeln!(Ref!int). When you force the template instantiation to writeln!int -- e.g. with an explicit cast, https://d.godbolt.org/z/6fKbMh731 -- the Ref!int output is the same as with int.

Regardless, I haven't seen a performance measurement, and it is most likely completely irrelevant for the performance of your program.

-Johan

August 17, 2021

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;
}

Wow you can alias this a function? TIL!

1 2
Next ›   Last »