-3

In my current understanding, when a function or a method is called, the data related to this method, say MethodA, is stored inside a stack frame to be kept track of during the execution of this method. And if this method in turn calls another method, say MethodB, the data related to MethodB will be stored in another stack frame which will be put on the top of the stack frame of MethodA.

  1. May I ask, in C#, are those stack frames stored on the stack? Or are they located in a separate place?

  2. If the stack frames are sitting on the stack, and say if in the stack frames there are some data of reference type, may I ask if the value of those data stored in those stack frames are the reference of the object which are pointing to the heap? Or if in such cases the object itself is stored in the stack frame on the stack?

Many thanks!

J-A-S
  • 368
  • 1
  • 8
  • The "stack frame" is an implementation detail, not a C#-specific thing. It should be blindingly obvious, given the name, that a "stack frame" is indeed stored "on the stack". See duplicate for a wealth of details about stack frames. For your second question (which should have been posted as a second question) see the many Q&A on the site that discuss reference types, such as https://stackoverflow.com/questions/30838504/variable-declaration-does-it-create-a-reference-to-the-actual-object-or-a-copy, and of course https://stackoverflow.com/questions/5057267/what-is-the-difference-between-a-refere – Peter Duniho Jul 23 '21 at 04:44
  • @PeterDuniho Thank you for your comment. I saw this article https://www.dcs.warwick.ac.uk/oldmodelling/other/eden/advanced/notes/stack.html and was thinking if the frame could be separated from the stack in some programming language. – J-A-S Jul 23 '21 at 04:57
  • @PeterDuniho "It should be blindingly obvious, given the name, that a "stack frame" is indeed stored "on the stack"." Come on, this is uncalled for. Should it also be "blindingly obvious" that every instance of `System.Collections.Generic.Stack` is stored on the stack, given that they have the same name? – Daniel McLaury Jul 23 '21 at 05:07
  • @DanielMcLaury: sorry, you're right. Perhaps instead I should have written "it should be blindingly obvious to anyone who actually Googled the phrase 'stack frame'...", since the very first hit is this Stack Overflow article: https://stackoverflow.com/questions/10057443/explain-the-concept-of-a-stack-frame-in-a-nutshell and it explains specifically where a stack frame lives, as do the next ten or so at least search results. I hope you're not trying to defend this question as if it showed any evidence of research or anything like that. – Peter Duniho Jul 23 '21 at 05:10
  • @PeterDuniho I should have written "confirm" rather than "ask". I did notice some of those articles and I wasn't sure if this applies to C# precisely in the way I understand it as I am a beginner to C# as well as to those implementation detail. Sincerely apologize for asking bad question. – J-A-S Jul 23 '21 at 05:44
  • You shouldn't care *where* the stack frame is stored, it might be on the moon. It might not even exist if the function is inlined. All you care is whether it is *logically* existing, so each function call *appears* to have new copies of variables. – Charlieface Jul 23 '21 at 10:52

1 Answers1

2

May I ask, in C#, are those stack frames stored on the stack? Or are they located in a separate place?

Yes, that's why it's called "the stack." It's a stack of call frames. When we say that a variable is stored "on the stack," we mean that it's stored inside of one of these call frames. The reason it's a stack is so that when a function returns its call frame can be popped off and we can return to the calling function.

If the stack frames are sitting on the stack, and say if in the stack frames there are some data of reference type, may I ask if the value of those data stored in those stack frames are the reference of the object? Or if in such cases the object itself is stored in the stack frame on the stack?

If you have a local variable in your method of reference type, that means that your call frame contains a few bytes that hold the address of that object on the heap.

Daniel McLaury
  • 4,047
  • 1
  • 15
  • 37
  • Thank you for your answer, may I ask a further question related to your answer for the second question? If we have some global variable or any non-local variable **of value type** in the method, are they accessed by reference (to where it locates on the stack)? Or are they accessed by other way? – J-A-S Jul 23 '21 at 04:55
  • [Deleted/reposted to remove idiocy; thanks @mjwills] C# doesn't have global variables. Static members of classes are stored in a special section of the heap. They couldn't live on the stack, because everything on the stack goes away as soon as the function it's in exits. – Daniel McLaury Jul 23 '21 at 05:34
  • May I ask if static members are not being boxed, how are they living on the heap? – J-A-S Jul 23 '21 at 05:50
  • @J-A-S: mjwills gave a link here, which he deleted with his comment, but see https://stackoverflow.com/questions/25741795/is-a-static-value-type-field-boxed-in-the-heap-in-c – Daniel McLaury Jul 23 '21 at 05:54
  • Thank you for the link. May I further ask, since those static members of value types lives on the heap, do variables in stack frame access them by their reference on the heap? Then, do they behave like reference type? – J-A-S Jul 23 '21 at 07:17
  • Also, may I ask if static as well as non-static members on the heap referenced by call frames are copied for each call frame? Since otherwise if we call the method recursively, different call frames might hold the same address and cause problems? – J-A-S Jul 23 '21 at 09:39
  • @J-A-S You seem to have a misunderstanding: the stack/heap difference is *implemetation-defined* and not relevant. A reference-type *itself * is never copied, only the reference to it. So a recursive function, each frame contains its own reference, which may or may not point to the same object. Whereas a value-type, it is *itself* copied, so each frame contains a new copy. – Charlieface Jul 23 '21 at 10:51
  • @Charlieface Thank you for your comments, could you please explain more on what you meant by “each frame contains **its own reference**, which **may or may not** point to the same object”? In my understanding, each entity on heap should have a unique, fixed memory address associated to it, and this address should be the reference storing in the variable on stack which is pointing to it. And if multiple frames are pointing to the same object, then they should all hold the same reference, then in recursion if modification is made to that object in one frame, all other frames will be affected – J-A-S Jul 23 '21 at 12:51
  • @Charlieface That’s the problem I said that might be caused. That’s why I think the object itself should be copied in some way... but I believe that I’m having some misunderstandings about what is happening there. Could you please point them out? Greatly appreciated :) – J-A-S Jul 23 '21 at 12:55
  • @J-A-S That is basically correct: there can be multiple references to a single reference-type object. In a recursive function (or any function for that matter), each call of the function contains a new set of variables on the stack. These variables are not copies of the actual object, they are copies of the reference to that object. So you can change the reference to point a different object, and the other frame's reference will not change. But if you modify properties of the object, all references that point to that object also change.... – Charlieface Jul 23 '21 at 13:15
  • @J-A-S ... Whereas value-type objects, the stack variable stores the actual value, which is copied to the next frame and is not a reference. – Charlieface Jul 23 '21 at 13:16
  • @Charlieface Thank you for your explanation. To make things clearer, may I ask 2 questions? 1. for value type fields (both static and non-static), I believe they are created on heap. May I confirm that for each method call, the stack frame is taking a copy from heap to the stack, so that the copies of those fields used in the execution of each method call are actually sitting on stack? (I thought the copies of the value type fields on heap which are used in stack frame are still on heap, which led me to think if stack frames need references to point to the value type on heap, which is weird) – J-A-S Jul 23 '21 at 14:28
  • @Charlieface 2. For the reference type related to the method, I'm still a bit confused. When multiple stack frames are created during recursion, are the variable referring to the same reference type in each frame all pointing to the same object on heap? If so, frames would not be independent to each other (since they could be "coupled" with each other through the modification on the same object on heap and affect each other's data) and such design makes no sense to me since I think the execution to each frame should be separated from others ...... – J-A-S Jul 23 '21 at 14:42
  • @Charlieface ...... as you said "*you can change the reference to point a different object, and the other frame's reference will not change*", but firstly, shouldn't this process of changing reference be automated by .NET during recursive calls? Secondly, speaking of recursive calls, since we are executing the same set of commands recursively, should the reference in each frame be changed to a copy of the same object? And hence the copy of the object on heap? – J-A-S Jul 23 '21 at 14:48
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/235233/discussion-between-charlieface-and-j-a-s). – Charlieface Jul 23 '21 at 15:28
  • @J-A-S https://chat.stackoverflow.com/rooms/235233/discussion-between-charlieface-and-j-a-s – Charlieface Jul 23 '21 at 15:36
  • @Charlieface Hi, sorry but there is still one thing I forgot to ask in the chatroom: since static value type of a class does not associate with specific instance of the class, and meanwhile, static value type live on the heap, may I ask, when we have a method that uses the static value type, how does the call stack access the static value type? And how does the call stack modify the static value type? – J-A-S Jul 23 '21 at 18:51
  • @J-A-S Depends if the struct is passed by value or by reference (the latter is with the `ref` keyword). For example, `void Foo(int someValue) { someValue = 5; }` is passing by value, so it's always copied and doesn't affect the original field. But `void Foo(ref int someValue) { someValue = 5; }` is passed by reference (you can pass a static field's reference from the heap no problem) and therefore `Foo` can change the original field. Note that `this` in a struct's instance methods is always passed internally as `ref` – Charlieface Jul 24 '21 at 22:27
  • @Charlieface Thank you for your explanation! May I ask 2 further questions: 1. internally, when the value or the reference of a static field is passed from the heap, is it passed directly on its own? Or is it passed as a part of the ```Type``` object? (I'm asking this because I saw the answer from https://stackoverflow.com/questions/14781993/how-exactly-do-static-fields-work-internally saying that the static fields are stored inside the ```Type``` object, so I'm wondering if ```Type``` object is to static field like the class instance is to instance field) ...... – J-A-S Jul 25 '21 at 05:26
  • @Charlieface ...... 2. May I confirm if we can talk about reference on the stack just like how we talk about reference on the heap? More specifically, if we have ```void Foo(ref int someValue) { someValue = 5; }``` where ```someValue``` is now a **local** variable of value type (so that it is living on the stack), may I ask if the ```ref``` keyword is forcing ```someValue``` to pass its reference **of the stack** and making ```someValue``` act as (metaphorically) "a reference type on the stack"? – J-A-S Jul 25 '21 at 05:34
  • @J-A-S 1. I suppose that's one way of looking at it. But internally, no that's not how it works. CLR has many different representations of a type, the internal structures are not directly related to an actual `Type` object. Somewhere within them there is a location for each static field. Again, the actual location is irrelevant, it may as well be the moon for all the difference it makes to you. 2. Yes that is exactly what it does (note that you can also have `ref` of an object, a ref of a ref) – Charlieface Jul 25 '21 at 05:36
  • @J-A-S I think we can bring this discussion to a close, there are a huge amount of internal details to the CLR: to satisfy your curiosity you can begin reading here https://mattwarren.org/2018/01/22/Resources-for-Learning-about-.NET-Internals/ – Charlieface Jul 25 '21 at 05:36
  • @Charlieface Thank you very much for your patience those days and helps, I've learnt a lot :) – J-A-S Jul 25 '21 at 05:45