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