digitalmars.D.learn - why local variables cannot be ref?
- Fanda Vacek (16/16) Nov 24 2019 Maybe I'm missing the thing, but I'm not able to declare local
- Rumbu (5/21) Nov 24 2019 Probably you are coming from C#. There are no reference variables
- Fanda Vacek (6/29) Nov 25 2019 Thanks for answer, I'm coming from C++. But anyway, pointers are
- rumbu (3/8) Nov 25 2019 Enjoy:
- rumbu (3/11) Nov 25 2019 sSorry, wrong link above.
- H. S. Teoh (6/8) Nov 25 2019 [...]
- Fanda Vacek (12/20) Nov 25 2019 void main() @safe
- H. S. Teoh (13/34) Nov 25 2019 Correct, taking the address of a local variable is not allowed because
- Jonathan M Davis (20/27) Nov 25 2019 That and taking the address of a local variable is @system, though with
- Dukc (5/19) Nov 25 2019 It's okay, but I'd prefer an alias, because your snippet uses the
- Timon Gehr (2/24) Nov 25 2019 This is not true. You can annotate main with @nogc.
- Fanda Vacek (11/32) Nov 25 2019 Yes alias can help, but my original need was like
Maybe I'm missing the thing, but I'm not able to declare local ref variable even if simple workaround exists. Is this preferred design pattern? ``` int main() { int a = 1; //ref int b = a; // Error: variable `tst_ref.main.b` only parameters or `foreach` declarations can be `ref` ref int b() { return a; } b = 2; assert(a == 2); return 0; } ``` Fanda
Nov 24 2019
On Monday, 25 November 2019 at 03:07:08 UTC, Fanda Vacek wrote:Maybe I'm missing the thing, but I'm not able to declare local ref variable even if simple workaround exists. Is this preferred design pattern? ``` int main() { int a = 1; //ref int b = a; // Error: variable `tst_ref.main.b` only parameters or `foreach` declarations can be `ref` ref int b() { return a; } b = 2; assert(a == 2); return 0; } ``` Fandain D, but you can use pointers like in: int* b = &a; *b = 2;
Nov 24 2019
On Monday, 25 November 2019 at 05:51:31 UTC, Rumbu wrote:On Monday, 25 November 2019 at 03:07:08 UTC, Fanda Vacek wrote:Thanks for answer, I'm coming from C++. But anyway, pointers are not allowed in safe code, so this is not always solution. Workaround exits even for safe code, so my question remains the same. What is a rationale for such a language design restriction, if it can be workarounded easily.Maybe I'm missing the thing, but I'm not able to declare local ref variable even if simple workaround exists. Is this preferred design pattern? ``` int main() { int a = 1; //ref int b = a; // Error: variable `tst_ref.main.b` only parameters or `foreach` declarations can be `ref` ref int b() { return a; } b = 2; assert(a == 2); return 0; } ``` Fandavariables in D, but you can use pointers like in: int* b = &a; *b = 2;
Nov 25 2019
On Monday, 25 November 2019 at 08:07:50 UTC, Fanda Vacek wrote:Thanks for answer, I'm coming from C++. But anyway, pointers are not allowed in safe code, so this is not always solution. Workaround exits even for safe code, so my question remains the same. What is a rationale for such a language design restriction, if it can be workarounded easily.Enjoy: https://forum.dlang.org/post/blgcfjqdhtusavlrgdjr forum.dlang.org
Nov 25 2019
On Monday, 25 November 2019 at 08:20:59 UTC, rumbu wrote:On Monday, 25 November 2019 at 08:07:50 UTC, Fanda Vacek wrote:sSorry, wrong link above. https://forum.dlang.org/thread/ruwapnhkuvozitefzplt forum.dlang.org?page=1Thanks for answer, I'm coming from C++. But anyway, pointers are not allowed in safe code, so this is not always solution. Workaround exits even for safe code, so my question remains the same. What is a rationale for such a language design restriction, if it can be workarounded easily.Enjoy: https://forum.dlang.org/post/blgcfjqdhtusavlrgdjr forum.dlang.org
Nov 25 2019
On Mon, Nov 25, 2019 at 08:07:50AM +0000, Fanda Vacek via Digitalmars-d-learn wrote: [...]But anyway, pointers are not allowed in safe code, so this is not always solution.[...] This is incorrect. Pointers *are* allowed in safe code. Pointer *arithmetic* is not allowed. --T
Nov 25 2019
On Monday, 25 November 2019 at 08:32:53 UTC, H. S. Teoh wrote:On Mon, Nov 25, 2019 at 08:07:50AM +0000, Fanda Vacek via Digitalmars-d-learn wrote: [...]void main() safe { int a = 1; int *b = &a; *b = 2; assert(a == 2); } does not compile for me with Error: cannot take address of local `a` in ` safe` function `main` so there must be more restrictions in safe code FandaBut anyway, pointers are not allowed in safe code, so this is not always solution.[...] This is incorrect. Pointers *are* allowed in safe code. Pointer *arithmetic* is not allowed. --T
Nov 25 2019
On Mon, Nov 25, 2019 at 08:39:08PM +0000, Fanda Vacek via Digitalmars-d-learn wrote:On Monday, 25 November 2019 at 08:32:53 UTC, H. S. Teoh wrote:[...]On Mon, Nov 25, 2019 at 08:07:50AM +0000, Fanda Vacek via Digitalmars-d-learn wrote: [...]But anyway, pointers are not allowed in safe code, so this is not always solution.[...] This is incorrect. Pointers *are* allowed in safe code. Pointer *arithmetic* is not allowed.void main() safe { int a = 1; int *b = &a; *b = 2; assert(a == 2); } does not compile for me with Error: cannot take address of local `a` in ` safe` function `main` so there must be more restrictions in safe codeCorrect, taking the address of a local variable is not allowed because of the possibility of a dangling pointer if the pointer leaks past the end of the variable's scope. With -dip1000, though, it should be allowed as long as you're not leaking the pointer past the lifetime of the local. Taking the address of a global is perfectly fine in safe code, as is using a pointer to a heap-allocated object (as long as no pointer arithmetic is involved). T -- If you're not part of the solution, you're part of the precipitate.
Nov 25 2019
On Monday, November 25, 2019 1:32:53 AM MST H. S. Teoh via Digitalmars-d- learn wrote:On Mon, Nov 25, 2019 at 08:07:50AM +0000, Fanda Vacek via Digitalmars-d-learn wrote: [...]That and taking the address of a local variable is system, though with -dip1000, it becomes safe by making the result scope, which restricts what you can do with it. And of course, trusted can be used where appropriate to make it so that system code can be used from safe code, though obviously, that means that it's up to the programmer to make sure that they verify that what the trusted code is doing is actually safe. Further, with regards to taking the address of a local variable being system, ref would be system for exactly the same reasons save for the fact that there are various restrictions in place to ensure that it can't be used in a manner which would allow the underlying pointer to exist longer than the address that it refers to. Allowing variables in general to be declared as ref instead of only allowing it in restricted circumstances such as function parameters and return types would put ref in the same system quagmire that exists with regards to taking the address of a local variable. By restricting ref, that problem is avoided, whereas pointers still allow for full freedom but in return, they require that certain operations that relate to them be system (like &, ++, and --). - Jonathan M DavisBut anyway, pointers are not allowed in safe code, so this is not always solution.[...] This is incorrect. Pointers *are* allowed in safe code. Pointer *arithmetic* is not allowed.
Nov 25 2019
On Monday, 25 November 2019 at 03:07:08 UTC, Fanda Vacek wrote:Is this preferred design pattern? ``` int main() { int a = 1; //ref int b = a; // Error: variable `tst_ref.main.b` only parameters or `foreach` declarations can be `ref` ref int b() { return a; } b = 2; assert(a == 2); return 0; } ``` FandaIt's okay, but I'd prefer an alias, because your snippet uses the heap needlessly (it puts variable a into heap to make sure there will be no stack corruption if you pass a pointer to function b() outside the main() function)
Nov 25 2019
On 25.11.19 10:00, Dukc wrote:On Monday, 25 November 2019 at 03:07:08 UTC, Fanda Vacek wrote:This is not true. You can annotate main with nogc.Is this preferred design pattern? ``` int main() { int a = 1; //ref int b = a; // Error: variable `tst_ref.main.b` only parameters or `foreach` declarations can be `ref` ref int b() { return a; } b = 2; assert(a == 2); return 0; } ``` FandaIt's okay, but I'd prefer an alias, because your snippet uses the heap needlessly (it puts variable a into heap to make sure there will be no stack corruption if you pass a pointer to function b() outside the main() function)
Nov 25 2019
On Monday, 25 November 2019 at 09:00:49 UTC, Dukc wrote:On Monday, 25 November 2019 at 03:07:08 UTC, Fanda Vacek wrote:Yes alias can help, but my original need was like void main() safe { int[] a = [1, 2]; alias head = a[0]; head = 2; assert(a[0] == 2); } there the alias doesn't work FandaIs this preferred design pattern? ``` int main() { int a = 1; //ref int b = a; // Error: variable `tst_ref.main.b` only parameters or `foreach` declarations can be `ref` ref int b() { return a; } b = 2; assert(a == 2); return 0; } ``` FandaIt's okay, but I'd prefer an alias, because your snippet uses the heap needlessly (it puts variable a into heap to make sure there will be no stack corruption if you pass a pointer to function b() outside the main() function)
Nov 25 2019