0

I am trying to work out where an int returned by a method will be stored. I assume it is the stack, but want to clarify. The scenario is as follows:

public int returnInt()
{
   var returnVal=1:
   Return returnVal;
}

In this case I know returnVal will be stored on the stack, and will pop when the returnInt method has run. In actual terms, returnVal is a value type, so will not be passed by reference.

The part I am not clear about is as follows:

public void callerMethod()
{
    var intVal=returnInt();
}

What I think happens here is the actual value is returned, and saved in a new memory location on the stack for callerMethod.

Can anyone confirm if this is correct? Please also feel free to correct anything else I have said that is not correct...

trincot
  • 317,000
  • 35
  • 244
  • 286
Alex
  • 3,730
  • 9
  • 43
  • 94
  • 4
    Where a return type is stored in c# is almost certainly an *implementation detail.* – Robert Harvey Nov 18 '19 at 06:02
  • @RobertHarvey can you expand? – Alex Nov 18 '19 at 06:03
  • 1
    Value types do assignment by value (hence the name). If you have two variables of the same value type, and you assign one variable to the other, the *value* associated with the right hand side variable is copied to the left hand side variable. Similarly, if you assign the return value of a function (that returns a value type) to a variable, the value is copied. When variables of a value type go out of scope, no cleanup is needed. Just about everything else is an implementation detail; something you don't need to think about. – Flydog57 Nov 18 '19 at 06:17
  • Is your question a duplicate of [this](https://stackoverflow.com/questions/17293680/is-integer-created-on-stack-or-heap) ? Are you asking whether ints live on the stack or the heap? Or are you asking [where methods live](https://stackoverflow.com/questions/32415085/does-the-code-block-of-a-method-live-in-the-stack-or-heap-at-the-moment-of-execu) (you seem to imply that you believe methods live on the stack-they don't live on either). Or are you asking if the memory location on the stack allocated for returnVal is reused for intVal? – Caius Jard Nov 18 '19 at 06:26
  • @Flydog57 that is the answer-if you write as an answer I will accept – Alex Nov 18 '19 at 06:26
  • There is no guarantee that `intVal` in your last example will ever be stored in memory, on the stack or the heap. It's possible that the JIT compiler will optimize the code such that `intVal` is always stored in a register. In general, there's no way for you to be sure, and no real need for you to be concerned about where (stack or heap) a particular value is being stored. – Jim Mischel Nov 18 '19 at 16:36

1 Answers1

1

The value in callerMethod() is a new value, independent of the value in returnInt().

I hope the example below helps.

static int myStaticInt = 333;
public static int returnInt()
{
    return myStaticInt;
}

public static void callerMethod()
{
    var i = returnInt();
    i += 100;
    Console.WriteLine(i);
}

public async static Task Main(string[] args)
{
    Console.WriteLine(myStaticInt);
    callerMethod();
    Console.WriteLine(myStaticInt);
}

Output

333
433
333

Result

myStaticInt is still 333.


Here is a relevant part from Passing Value-Type Parameters (C# Programming Guide):

A value-type variable contains its data directly as opposed to a reference-type variable, which contains a reference to its data. Passing a value-type variable to a method by value means passing a copy of the variable to the method. Any changes to the parameter that take place inside the method have no affect on the original data stored in the argument variable.

Here is a bit about assignment from Types part of C# specification.

Assignment to a variable of a value type creates a copy of the value being assigned. This differs from assignment to a variable of a reference type, which copies the reference but not the object identified by the reference.


Passing and returning value types by reference

Please note that it is possible to pass, and return, value types by reference.

Please see Passing Value Types by Reference section of Passing Value-Type Parameters (C# Programming Guide) and Ref returns and ref locals.

Equipped with this knowledge, let's now modify our example and examine the result.

static int myStaticInt = 333;
public static ref int returnInt()
{
    //var returnVal = 1;
    return ref myStaticInt;
}

public static void callerMethod()
{
    ref var i = ref returnInt();
    i += 100;
    Console.WriteLine(i);
}

public async static Task Main(string[] args)
{
    Console.WriteLine(myStaticInt);
    callerMethod();
    Console.WriteLine(myStaticInt);
}

Output

333
433
433

Result

myStaticInt is now 433, not the original 333.

tymtam
  • 31,798
  • 8
  • 86
  • 126