How to fix this sample?

Hi there.
I found an example on a site but compiler does not agree it is correct.

fn main() {
    let x = 5;
    let y = 10;
    let z = add(&x, &y);
    println!("{}", z);
}

fn add<'a>(a: &'a i32, b: &'a i32) -> &'a i32 {
    &((a + b))
}

this is what compiler complains:

error[E0515]: cannot return reference to temporary value

my fault but don't understand... Any idea? thx,

The way add is defined, it returns a reference to an integer. But that integer must be stored somewhere in memory. Inside the add function, the value will be on the stack. But when you return from the function, that stack frame is gone, so you can't refer to the result. That means, you must store the integer somewhere or return an owned integer, like this:

fn main() {
    let x = 5;
    let y = 10;
    let z = add(&x, &y);
    println!("{}", z);
}

fn add<'a, 'b>(a: &'a i32, b: &'b i32) -> i32 {
    a + b
}

(Playground)

Note that you also should not require the two arguments 'a and 'b to be the same. They can be different lifetimes.


As integers can be copied (they implement the Copy trait), you would idiomatically just write:

fn main() {
    let x = 5;
    let y = 10;
    let z = add(x, y);
    println!("{}", z);
}

fn add(a: i32, b: i32) -> i32 {
    a + b
}

(Playground)

2 Likes

This does not matter at all unless the lifetimes are also used in more complex ways. When the lifetimes are just used for references passed to the function, they are covariant, so the possibly longer lifetimes at the call site can be shortened to produce references matching the function signature — the only lifetimes which this doesn't work for are lifetimes that don't outlive the function call and therefore aren't valid to use.

2 Likes

I will be replaced with an AI soon. :robot:

You are right in case of shared references, but I think this could cause problems when there are mutable references? I generally try to not set lifetimes equal unless there is a requirement for them to be equal because I sometimes ran into bad errors later (when using a function, even if the function by itself does compile). So do you think my advice still should be given as general advice?

I tried to come up with a &mut example that doesn't compile but didn't find one.

1 Like

A mutable reference &'lt T is still covariant in 'lt, but invariant in T. You do have to be precise about lifetimes appearing in the target of a mutable reference, but not typically with the lifetime of the mutable reference itself (as long as you're receiving the mutable reference in a function parameter; other situations may care more).

1 Like

Out of curiosity I also asked ChatGPT.... I find it quite disturbing. However, if I understood correctly, the problem is that z is created on the fly and tied to a function that drops when finished and the reference to i32 is lost...is that it?
thx to you all

The problem exists in add, z isn't really involved in the error. You get the same error if you remove the main function. But yes, the value that you're trying to return is gone by the time the function returns.

Return by temporary reference gives access to something that has already existed before the function was called, and has been stored some place that outlives the scope of the lifetime.

The result of a+b did not exist before you called add, hasn't already been stored previously outside of add where the lifetime 'a came from, and therefore you can't expose access to it via a temporary reference.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.