digitalmars.D.learn - What am I doing wrong here?
- JG (42/42) May 06 2022 This isn't code to be used for anything (just understanding).
- =?UTF-8?Q?Ali_=c3=87ehreli?= (50/51) May 06 2022 This is a segmentation fault. Reduced:
- JG (4/9) May 06 2022 Hi, thanks. That was quite silly. (I was thinking the variable
- Salih Dincer (7/26) May 06 2022 The value returned by the delegate structure in the above line is
- JG (50/77) May 08 2022 What do you mean?
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
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
On Friday, 6 May 2022 at 18:35:40 UTC, Ali Çehreli wrote:On 5/6/22 11:04, JG wrote: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).[...]This is a segmentation fault. Reduced: import std; [...]
May 06 2022
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
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: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.```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 08 2022