What shouldn't you return from a local variable?

Jul 15, 2020 at 7:48pm
Hi. I'm learning C and C++ and read somewhere that you can't return local variables like so

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include "stdio.h"

typedef struct Foo
{
	int fooval;
} Foo;

int GetInt(int a)
{
   int retVal;
   retVal = a + 1;
   return retVal;
}

Foo GetFoo()
{
   Foo f;
   f.fooval = 8999;
   return f;
}

int main(int argc, char**argv)
{
   int result1 = GetInt(100);
   printf("Result1: %d\n", result1); 
   int result2 = GetInt(result1);
   printf("Result2: %d\n", result2);
   
   // You can also return user defined types by value
   Foo result3 = GetFoo();
   printf("Result3: %d\n", result3);
   return 0;
}


But it seems to work ok. In fact, learncpp says this is returning by value where retVal from the local scope has been copied. So maybe I've incorrectly recalled the rule about what not to do. One thing I tried (that I kinda knew was naughty) was:

1
2
3
4
5
6
7
8
9
10
int* GetInt(int a)
{
   int result = a + 1;
   return &result;
}

int main(int argc, char**argv)
{
   std::cout << *GetInt(100) << '\n';
}


which segfaults and compiles with a warning. So perhaps what I'd forgotten was that it's ok to return stuff by value (understanding that it's copied) but you shouldn't return pointers to stuff declared locally. I wanted to verify this.

Also, the return-by-value/reference and the rule about not returning a pointer to local memory are the same in C right?

https://www.learncpp.com/cpp-tutorial/74a-returning-values-by-value-reference-and-address/
Jul 15, 2020 at 7:51pm
You should not return pointers to locals, nor references to locals. Simply returning a local creates a copy of that local which, unusual object semantics notwithstanding, is perfectly safe.
Jul 15, 2020 at 7:57pm
you must not return the local variable itself to something that would attempt to use it after it has been destroyed.

as you noted in your naughty code, result died when the function ended and its address is not safe to use anymore. You can fix this with the static keyword: it is ok to do what you did if result had been static, because then it would exist after the function exits.

That is is in a tiny nutshell: if you return something that no longer exists when the function ends, it is wrong. That can be tricky to figure out as a beginner: a pointer created with a new returned still exists because you didn't delete the memory, but a pointer to a local variable does not because the local variable was destroyed, subtle differences there.

yes, its the same in C and every other language as well. Do not return the address of something that is about to harikari. Some languages that have some sort of built in memory stuff with reference tracking may be an exception, I do not know, I have never tried to abuse that.
Last edited on Jul 15, 2020 at 8:00pm
Jul 15, 2020 at 8:20pm
Great thanks. I also tried with references and you get segfault there as well.
Jul 15, 2020 at 8:57pm
please note that a segfault is not guaranteed, so be careful when coding and read the warnings as these kind of errors are hard to detect and trace.
Topic archived. No new replies allowed.