www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Returning value by ref does not create a ref. Is this intentional?

reply Tejas <notrealemail gmail.com> writes:
```d
import std.stdio:writeln;

ref int func(return ref int a){
     a = 6; // modifies a as expected
     return a;
}
void main(){
     int a = 5;
     auto c = func(a); // I expected c to alias a here
     c = 10; // Expected to modify a as well
     writeln(a); // prints 6 :(
}
```

The [spec](https://dlang.org/spec/function.html#ref-functions) 
states:

 Ref functions allow functions to return by reference, meaning 
 that the return value must be an lvalue, and the lvalue is 
 returned, not the rvalue.
Then why does the reference to `a` not get returned ?
Jan 04 2022
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Wednesday, 5 January 2022 at 04:35:12 UTC, Tejas wrote:
 ```d
 import std.stdio:writeln;

 ref int func(return ref int a){
     a = 6; // modifies a as expected
     return a;
 }
 void main(){
     int a = 5;
     auto c = func(a); // I expected c to alias a here
     c = 10; // Expected to modify a as well
     writeln(a); // prints 6 :(
 }
 ```
Local variables cannot be references, so when you assign the reference returned from `func` to the variable `auto c`, a copy is created. To make this work the way you want it to, you must use a pointer: ```d int a = 5; auto p = &func(a); // use & to get a pointer *p = 10; writeln(a); // prints 10 ```
Jan 04 2022
parent reply Tejas <notrealemail gmail.com> writes:
On Wednesday, 5 January 2022 at 05:15:30 UTC, Paul Backus wrote:
 On Wednesday, 5 January 2022 at 04:35:12 UTC, Tejas wrote:
 ```d
 import std.stdio:writeln;

 ref int func(return ref int a){
     a = 6; // modifies a as expected
     return a;
 }
 void main(){
     int a = 5;
     auto c = func(a); // I expected c to alias a here
     c = 10; // Expected to modify a as well
     writeln(a); // prints 6 :(
 }
 ```
Local variables cannot be references, so when you assign the reference returned from `func` to the variable `auto c`, a copy is created. To make this work the way you want it to, you must use a pointer: ```d int a = 5; auto p = &func(a); // use & to get a pointer *p = 10; writeln(a); // prints 10 ```
The entire reason I wanted to get a `ref` was so that I can avoid the `*` :( Didn't know you could take the address of a function _invocation_ though, so asking this wasn't completely redundant Thank you :D Guess I'll be stuck with ol' `struct Ref(T){...}`
Jan 04 2022
parent reply Dennis <dkorpel gmail.com> writes:
On Wednesday, 5 January 2022 at 05:38:45 UTC, Tejas wrote:
 The entire reason I wanted to get a `ref` was so that I can 
 avoid the `*` :(
I don't know what the real code behind the reduced example is, but maybe you can structure your code such that the subsequent modification `c = 10` happens in its own function. Then you can pass the result of `func(a)` to that function by `ref`.
Jan 05 2022
parent Tejas <notrealemail gmail.com> writes:
On Wednesday, 5 January 2022 at 08:58:44 UTC, Dennis wrote:
 On Wednesday, 5 January 2022 at 05:38:45 UTC, Tejas wrote:
 The entire reason I wanted to get a `ref` was so that I can 
 avoid the `*` :(
I don't know what the real code behind the reduced example is, but maybe you can structure your code such that the subsequent modification `c = 10` happens in its own function. Then you can pass the result of `func(a)` to that function by `ref`.
There isn't any complex code behind this. I was simply trying to emulate C++'s `int&`(or `T&` in general)
Jan 05 2022
prev sibling parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Wednesday, 5 January 2022 at 04:35:12 UTC, Tejas wrote:
 ```d
 import std.stdio:writeln;

 ref int func(return ref int a){
     a = 6; // modifies a as expected
     return a;
 }
 void main(){
     int a = 5;
     auto c = func(a); // I expected c to alias a here
     c = 10; // Expected to modify a as well
     writeln(a); // prints 6 :(
 }
 ```

 The [spec](https://dlang.org/spec/function.html#ref-functions) 
 states:

 Ref functions allow functions to return by reference, meaning 
 that the return value must be an lvalue, and the lvalue is 
 returned, not the rvalue.
Then why does the reference to `a` not get returned ?
It is returned. But initializing `c` with it makes a copy. This will mutate `a`: ``` func(a) = 10; ```
Jan 04 2022
parent Tejas <notrealemail gmail.com> writes:
On Wednesday, 5 January 2022 at 05:17:10 UTC, Stanislav Blinov 
wrote:


 It is returned. But initializing `c` with it makes a copy.
Oh... Wish we had real `ref` ;(
 This will mutate `a`:

 ```
 func(a) = 10;
 ```
Thank you for your help!
Jan 04 2022