With dmd v2.088.0-rc.1 (and earlier):
@safe:
int* addr(return ref int b) {
return &b;
}
struct S
{
int i;
}
auto s() {return S();}
void main(){
//auto p = addr(S().i); // cannot modify constant expression `S(0).i`
auto p = addr(s().i);
(*p)++;
}
Here the problem is that p outlives the int passed to addr. I think `return &b` in addr should not be allowed, because the returned pointer can live longer than the argument passed to the `ref int b` parameter.
Allowing &b to be returned also makes enhancing D to support @safe smart containers harder than it needs to be, requiring flow analysis - any ref can be turned into a scope pointer which lives longer.
Comment #1 by nick — 2019-08-30T15:48:15Z
This is with -dip1000.
Comment #2 by dlang-bot — 2020-03-19T07:54:14Z
@WalterBright created dlang/dmd pull request #10945 "fix Issue 20183 - Assigning statement scope of struct literal or temp…" fixing this issue:
- fix Issue 20183 - Assigning statement scope of struct literal or temporary to variable with longer lifetime
https://github.com/dlang/dmd/pull/10945
Comment #3 by bugzilla — 2020-03-19T07:55:49Z
The problem is that the lifetime of a struct literal or temporary is only to the end of the expression it appears in. Assigning the address of them to a longer lived variable is not valid.
Comment #4 by dlang-bot — 2020-06-10T09:44:23Z
dlang/dmd pull request #10945 "fix Issue 20183 - Assigning statement scope of struct literal or temp…" was merged into master:
- 37a695f4839b2f50d64535640382cb777459585b by Walter Bright:
fix Issue 20183 - Assigning statement scope of struct literal or temporary to variable with longer lifetime
https://github.com/dlang/dmd/pull/10945