www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - What am I doing wrong here?

reply JG <someone somewhere.com> writes:
This isn't code to be used for anything (just understanding).
```d
import std;

struct Delegate(A,B) {
     B function(void* ptr, A a) f;
     void* data;
     B opCall(A a) {
         return f(data,a);
     }
}

auto toDelegate(A, B,S)(S s) {
     static B f(void* ptr, A a) {
         return (*(cast(S*) ptr))(a);
     }
     Delegate!(A,B) ret;
     ret.f=&f;
     ret.data= cast(void*) &s;
     return ret;
}

struct Adder {
     int a;
     int opCall(int b) { return a+b; }
}
auto adder(int a) {
     auto ret = Adder.init;
     ret.a=a;
     return ret;
}

void main() {
     auto g = adder(5);
     g(5).writeln;
     auto d = toDelegate!(int, int)(g);
     d(5).writeln;
     auto a =7;
     auto h = (int b)=>a+b;
     auto d1 = toDelegate!(int,int)(h);
     void* ptr = cast(void*) &h;
     (*cast(int delegate(int)*) ptr)(10).writeln;
     d1(10).writeln;
     h(10).writeln;
}
```
May 06 2022
next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 5/6/22 11:04, JG wrote:
 This isn't code to be used for anything (just understanding).
This is a segmentation fault. Reduced: import std; struct Delegate(A,B) { B function(void* ptr, A a) f; void* data; B opCall(A a) { return f(data,a); } } auto toDelegate(A, B,S)(S s) { static B f(void* ptr, A a) { return (*(cast(S*) ptr))(a); } Delegate!(A,B) ret; ret.f=&f; ret.data= cast(void*) &s; return ret; } void main() { auto a =7; auto h = (int b)=>a+b; auto d1 = toDelegate!(int,int)(h); d1(10); } This is what I did to figure out: 1) Compiled with -g 2) Started gdb (my compiled program is 'deneme'): $ gdb --args ./deneme 3) Entered 'run' in gdb You are storing the address of the local variable 's' here: ret.data= cast(void*) &s; One good news is, compiling with -dip1000 catches this mistake. :) Another solution is to pass 's' by ref, in which case you have to make sure that variable lives long enough when its used. // vvv auto toDelegate(A, B,S)(ref S s) { // ... } Further, you can mix -dip1000 and ref if you protect the code by also adding 'return' to the parameter: // vvvvvvvvvv auto toDelegate(A, B,S)(return ref S s) { // ... } I am surprised that 'in' does not provide similar protection. // vv auto toDelegate(A, B,S)(in S s) { The code compiles but crashes. (?) Ali
May 06 2022
parent JG <someone somewhere.com> writes:
On Friday, 6 May 2022 at 18:35:40 UTC, Ali Çehreli wrote:
 On 5/6/22 11:04, JG wrote:
 [...]
This is a segmentation fault. Reduced: import std; [...]
Hi, thanks. That was quite silly. (I was thinking the variable lives to the end of scope of main but not thinking about that I am passing by value).
May 06 2022
prev sibling parent reply Salih Dincer <salihdb hotmail.com> writes:
On Friday, 6 May 2022 at 18:04:13 UTC, JG wrote:
 ```d
 //...
 struct Adder {
     int a;
     int opCall(int b) { return a+b; }
 }
 auto adder(int a) {
     auto ret = Adder.init;
     ret.a=a;
     return ret;
 }

 void main() {
     auto g = adder(5);
     g(5).writeln; // 10
     auto d = toDelegate!(int, int)(g);
     d(5).writeln; // 10
 // ...
 }
 ```
The value returned by the delegate structure in the above line is 10. Its parameter is 5, but if you do it to 21, you will get 42. So it doesn't have the ability to delegate Adder. In summary, the sum function isn't executing. Instead, its value gets double. SDB 79
May 06 2022
parent JG <someone somewhere.com> writes:
On Saturday, 7 May 2022 at 02:29:59 UTC, Salih Dincer wrote:
 On Friday, 6 May 2022 at 18:04:13 UTC, JG wrote:
 ```d
 //...
 struct Adder {
     int a;
     int opCall(int b) { return a+b; }
 }
 auto adder(int a) {
     auto ret = Adder.init;
     ret.a=a;
     return ret;
 }

 void main() {
     auto g = adder(5);
     g(5).writeln; // 10
     auto d = toDelegate!(int, int)(g);
     d(5).writeln; // 10
 // ...
 }
 ```
The value returned by the delegate structure in the above line is 10. Its parameter is 5, but if you do it to 21, you will get 42. So it doesn't have the ability to delegate Adder. In summary, the sum function isn't executing. Instead, its value gets double. SDB 79
What do you mean? ```d import std; struct Delegate(A,B) { B function(void* ptr, A a) f; void* data; B opCall(A a) { return f(data,a); } } auto toDelegate(A, B,S)(ref S s) { static B f(void* ptr, A a) { return (*(cast(S*) ptr))(a); } Delegate!(A,B) ret; ret.f=&f; ret.data= cast(void*) &s; return ret; } struct Adder { int a; int opCall(int b) { return a+b; } } auto adder(int a) { auto ret = Adder.init; ret.a=a; return ret; } void main() { auto g = adder(5); g(5).writeln; auto d = toDelegate!(int, int)(g); d(41).writeln; auto a =7; auto h = (int b)=>a+b; auto d1 = toDelegate!(int,int)(h); void* ptr = cast(void*) &h; (*cast(int delegate(int)*) ptr)(10).writeln; d1(21).writeln; h(32).writeln; } ``` Output: 10 46 17 28 39 Which is what is expected.
May 08 2022