Modify the contents of the memory address of the return of a function
Yes this is well-defined C.
The anonymous temporary int
s created by get_val...()
have a lifetime contemporaneous with the entire statement in which they are created.
But note that you take a value copy of each of these int
s when you call print_and_redefine_ints
so there's nothing particularly special going on here.
(Note that you would not be able to bind pointers to the anonymous temporary int
s to int*
function parameters though.)
A draw may explain more than some text. I'll use only 1 get_val1()
in that example.
print_and_redefine_ints(get_val1());
|
|
[CALL]
|
|
V
int get_val1()
{
int ret = 1;<----------------------------------------------------+
return ret; |
} | |
| |
[COPY OF VALUE] |
| |
| |
+---+ |
| |
| |
V |
void print_and_redefine_ints(int val1) { |
printf("val1 %d\n"); ^ |
redefine_ints(&val1); | |
| +--------------------------------------------+ |
| | |
[POINTER AKA REFERENCE] | |
| | |
| | |
V | |
void redefine_ints(int *val1) { | |
*val1 = 10; //<---- the value is changed, then its referenced value (this one, NOT THIS ONE) is changed too
} |
|
+---+
|
[VALUE CHANGED]
|
|
V
printf("rval1 %d\n", val1);
printf("original val1 %d\n", get_val1()); //if you add this line, you'll notice the returned value of get_val1() is still 1
}
Is it possible to modify the contents of the memory address of the return (value) of a function?
No, it is not.
However, that is not the case here. In your code, the return values of get_val<n>()
function calls are stored in the function parameters int val1
, int val2
, int val3
. They are local to the called function. The lifetime of those variables are the function execution period.
Quoting C11
, chapter §6.2.1,
[...] If the declarator or type specifier that declares the identifier appears inside a block or within the list of parameter declarations in a function definition, the identifier has block scope, which terminates at the end of the associated block. [....]
and, from §6.9.1, Function definition,
Each parameter has automatic storage duration; its identifier is an lvalue
Thus, just like any other local variable, you can modify the content of those variables using their address.