-1

the case is

 int func(void){
        int A = 10;
        int B = 20;
        return A+B
    }

which is being called by the main function

int main(void){
    int retVal = func();
    return 0;
}

in the function func() two local variables will be stored onto the stack for the scope of func() but where does the result of A+B stored?

and over the call by reference, how reliable this method is?

what is the difference between following function bodies

int func(void){
    int A = 20;
    return A;
}

and

int* func(void){
    int A = 20;
    return &A;
}

why returning the values does not throw the error of the segmentation fault but returning the address do?

aTechieSmile
  • 139
  • 1
  • 1
  • 11
  • "Reliable" in what sense? – Scott Hunter May 09 '22 at 12:05
  • 1
    The compiler might inline the code of `func`. It might even be able to do the calculations at compile-time so the values are not stored at all. And in this specific case, since `retVal` isn't used the compiler will most likely not call the function at all and just ignore it and the `retVal` variable. – Some programmer dude May 09 '22 at 12:06
  • @ScottHunter , like in the case of the returning the address of the local variable from the function, it will be dangling pointer, but same case for returning the value of the local variable, I have never seen any issues with that. – aTechieSmile May 09 '22 at 12:10

3 Answers3

1

where does the result of A+B stored?

This strongly depends on specific architecture and specific calling convension - every architecture is different. Let's inspect the most common one - x86-64 on Linux (see https://en.wikipedia.org/wiki/X86-64 , https://en.wikipedia.org/wiki/X86_calling_conventions#cdecl , Where is the x86-64 System V ABI documented? , https://en.wikibooks.org/wiki/X86_Assembly/X86_Architecture ).

The function you presented is compiled by gcc to godbolt link:

func:
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-4], 10
        mov     DWORD PTR [rbp-8], 20
        mov     edx, DWORD PTR [rbp-4]
        mov     eax, DWORD PTR [rbp-8]
        add     eax, edx
        pop     rbp
        ret

On x86-64 the return value is stored inside eax register. The add eax, edx puts the result of the addition inside eax register. After setting eax, the function than returns, and main can read the content of eax register if he wants to get the return value.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • this is completely understandable, but according to the programming standards is it not recommended to return the address of the local variable, because of the dangling pointer issue so over this how is this method reliable to directly return the value or the expressions? – aTechieSmile May 09 '22 at 12:28
  • @geeeeekyDeveloper: This method *is* directly returning the value. It’s not returning an address. I’m not sure I understand your question. – John Bode May 09 '22 at 12:39
  • @JohnBode I have edited my question, it might help you to understand my question properly – aTechieSmile May 09 '22 at 12:47
1

Given that you tagged this with the "C" keyword, it is worth saying that the intent in the early days of C was that the return value, as an integer or a pointer, should fit in a processor register, so no memory is allocated to storing the value.

The calling function may need to declare a variable to store the result into, and it is responsible for that allocation. Immediately on return from the function the caller will stash that agreed processor register value into the memory it has reserved. Of course, that may not be necessary if the value is used immediately for some other calculation.

When returning a pointer, what the pointer points to is a problem for the programmer: you. As you have found, if you try to access a value you only declared as a local variable in the called function and returned using a pointer, the local variable space - the function call stack - is heavily reused, and your value will quickly be junked.

Of course, you can return floating point values and structs in modern C and C++, which often needs different handling. Usually the caller function has to reserve space for the called function to store these larger objects into.

Note that the compilers are often able to inline and optimise code to use available registers, rather than repeatedly using the agreed registers, and sometimes even replace small structures with a set of registers.

Tools like godbolt can let you easily see what the compiler has done to your code.

Gem Taylor
  • 5,381
  • 1
  • 9
  • 27
0

in the function func() two local variables will be stored onto the stack for the scope of func() but where does the result of A+B stored?

Depends on the specific calling convention for the target architecture, usually in a register (such eax on x86).

what is the difference between following function bodies

int func(void){
    int A = 20;
    return A;
}

and

int* func(void){
    int A = 20;
    return &A;
}

In the first case you are returning the result of the expression A, which is simply the integer value 20; IOW, the value 20 is written to some register or other memory location, which is read by the calling function.

In the second case you are returning the result of the expression &A, which is the address of the variable A in func. The problem with this is that once func exits A ceases to exist and that memory location becomes available for something else to use; the pointer value is no longer valid, and the behavior on dereferencing an invalid pointer is undefined.

John Bode
  • 119,563
  • 19
  • 122
  • 198