digitalmars.D.learn - cast ref pointer
- =?UTF-8?B?THXDrXM=?= Marques (26/26) Jan 18 2018 This works, obviously (i.e. it prints 42):
- Adam D. Ruppe (4/7) Jan 18 2018 Simply define an intermediate.
- =?UTF-8?B?THXDrXM=?= Marques (9/12) Jan 18 2018 In my actual case bar also receives its pointer by ref, so you
- ag0aep6g (15/43) Jan 18 2018 You need a reinterpret-style cast here to get an lvalue:
- =?UTF-8?B?THXDrXM=?= Marques (5/13) Jan 18 2018 Right, that's what I wanted. Ugh, for some reason I was totally
- Steven Schveighoffer (8/21) Jan 18 2018 Note, this, to me, seems odd. Of course this is not the full case, but
- =?UTF-8?B?THXDrXM=?= Marques (4/9) Jan 18 2018 Yeah, I went overboard in reducing my scenario :( The actual
- Adam D. Ruppe (9/10) Jan 18 2018 you might be better off receiving a pointer-to-pointer instead of
This works, obviously (i.e. it prints 42): void foo(ref int* a) { static int j = 42; a = &j; } void bar(int* ptr) { foo(ptr); writeln(*ptr); } void main() { int i = 7; bar(&i); } Unfortunately, if bar for some reason receives a void* pointer (e.g. C callback) this doesn't work: void bar(void* ptr) { foo(cast(int*) ptr); // error writeln(*cast(int*) *ptr); } I think the underlying idea is sound (use ptr as an lvalue, but with int* type), but since you can't cast(ref int*), I don't know how to express it in D code.
Jan 18 2018
On Thursday, 18 January 2018 at 15:25:38 UTC, Luís Marques wrote:I think the underlying idea is sound (use ptr as an lvalue, but with int* type), but since you can't cast(ref int*), I don't know how to express it in D code.Simply define an intermediate. int* tmp = cast(int*) that_void_pointer; foo(tmp);
Jan 18 2018
On Thursday, 18 January 2018 at 16:08:32 UTC, Adam D. Ruppe wrote:Simply define an intermediate. int* tmp = cast(int*) that_void_pointer; foo(tmp);In my actual case bar also receives its pointer by ref, so you would have to do something like: int* tmp = cast(int*) that_void_pointer; foo(tmp); that_void_pointer = tmp; This is a bit more noisy than what I would prefers (a more care is needed to check if this is properly optimized away), that's why I was looking for a more direct route, like a cast.
Jan 18 2018
On 01/18/2018 04:25 PM, Luís Marques wrote:This works, obviously (i.e. it prints 42): void foo(ref int* a) { static int j = 42; a = &j; } void bar(int* ptr) { foo(ptr); writeln(*ptr); } void main() { int i = 7; bar(&i); } Unfortunately, if bar for some reason receives a void* pointer (e.g. C callback) this doesn't work: void bar(void* ptr) { foo(cast(int*) ptr); // errorYou need a reinterpret-style cast here to get an lvalue: foo(* cast(int**) &ptr); The result has the same type (int*), but it refers to the very same memory location as `&ptr` does. So it's not just a temporary value, and it can be passed in a `ref` parameter.writeln(*cast(int*) *ptr);You're dereferencing twice here. Do it only once, after casting: writeln(* cast(int*) ptr);}Alernatively, you can make a local variable for the casted pointer and use that instead of the `ptr`: int* casted_ptr = cast(int*) ptr; foo(casted_ptr); writeln(*casted_ptr); That way, `ptr` itself won't be updated by `foo`, of course. But `ptr` isn't a `ref` parameter, so this only affects the insides of `bar` anyway.
Jan 18 2018
On Thursday, 18 January 2018 at 16:14:18 UTC, ag0aep6g wrote:On 01/18/2018 04:25 PM, Luís Marques wrote: You need a reinterpret-style cast here to get an lvalue: foo(* cast(int**) &ptr);Right, that's what I wanted. Ugh, for some reason I was totally confused about this :-)That was just a typo.writeln(*cast(int*) *ptr);You're dereferencing twice here. Do it only once, after casting:That way, `ptr` itself won't be updated by `foo`, of course. But `ptr` isn't a `ref` parameter, so this only affects the insides of `bar` anyway.Yeah, it was a bad example.
Jan 18 2018
On 1/18/18 10:25 AM, Luís Marques wrote:This works, obviously (i.e. it prints 42): void foo(ref int* a) { static int j = 42; a = &j; } void bar(int* ptr) { foo(ptr); writeln(*ptr); }Note, this, to me, seems odd. Of course this is not the full case, but you are not affecting anything except for the value of the local `ptr`. So I would be concerned this may not be what you want (if you are looking to affect something outside the callback). Other than that, the other responders are right, you just need to reinterpret the pointer. -Steve
Jan 18 2018
On Thursday, 18 January 2018 at 16:20:35 UTC, Steven Schveighoffer wrote:Note, this, to me, seems odd. Of course this is not the full case, but you are not affecting anything except for the value of the local `ptr`. So I would be concerned this may not be what you want (if you are looking to affect something outside the callback).Yeah, I went overboard in reducing my scenario :( The actual function bar also receives by ref its pointer.
Jan 18 2018
On Thursday, 18 January 2018 at 16:26:54 UTC, Luís Marques wrote:The actual function bar also receives by ref its pointer.you might be better off receiving a pointer-to-pointer instead of ref. Then it will be encoded in the type and thus you can cast outer layers too and use intermediate more easily if you need. void foo(void** f) { bar(cast(int**) f); } int* a; foo(&a);
Jan 18 2018