I am interested to know what happens behind the scenes when I pass a value type by reference using a "ref" or "out" operators in .NET. I know that passing by value has "copy" semantics. So, when I pass a value type into a function by reference, does the variable get boxed into a reference type, stored on the heap, and then a reference to it is passed instead?
Asked
Active
Viewed 84 times
1 Answers
1
No. There are special CIL instructions such as the ldind
family (for local variables of integral type) and ldflda
(for object fields) that push the address of something on the stack.
The receiving method uses other appropriate instructions to dereference that address and read or write its value. So in a nutshell, ref
and out
parameters are really just pointers.

Jon
- 428,835
- 81
- 738
- 806
-
Jon, thanks for the explanation. I guess my point of confusion was how the value type variable in the lower frame on the stack is accessed without popping the call stack. Are you saying that when a pointer is passed into a function, that local variable is accessed directly in a way similar to how it is done on the heap? – user2502844 Jun 20 '13 at 19:42
-
@user2502844: Yes, because you are passing a pointer-to-local-var to a function that you call; it will obviously return before you do, so the pointer-to-local is going to be good for the duration of its lifetime -- no problems there! Note that this works only as long as `ref` is limited to passing arguments; if you could *store* a `ref` then lifetime-related problems would appear. [Eric Lippert explains in detail](http://stackoverflow.com/a/2982037/50079). – Jon Jun 20 '13 at 22:26
-
in terms of performance, do you think it would be better to pass by ref? In theory, if no copy needs to be made, this would result in faster execution, right? Or am I completely off here? – user2502844 Jun 27 '13 at 15:03
-
@user2502844: No, because no copy is being made anyway for all reference types. For value types it depends if not making a copy will offset the cost of the extra indirection through the pointer whenever you want to access the value. **But all of this is irrelevant: using references or not should be a matter of correct semantics, not performance.** If you intend to modify the `ref`d argument then you have to use `ref`; if you don't, then don't use `ref`, period. – Jon Jun 27 '13 at 15:25