pass types by ref or value

J

Jon Slaughter

I'm reading a book on C# and it says there are 4 ways of passing types:

1. Pass value type by value
2. Pass value type by reference
3. Pass reference by value
4. Pass reference by reference.

My interpretation:

1. Essentially pushes the value type on the stack
2. Boxes the value type? pushes a pointer to the value type on the stack
3. since a reference is essentially a pointer we are pushing the pointer of
the "reference"(object).
4. Boxing the reference type. Pushing a pointer to the reference type on the
stack.

so 1 is equivilent to 3 and 2 to 4 in the sense that the same idea is
involved but just the context is different? 1 and 3 pushes the actual type's
value while 2 and 4 push a pointer to the memory location of the value.

Thanks,
Jon
 
M

Michael Nemtsev

Hello Jon,

Jon's opened this topic pretty clear
Read this http://www.yoda.arachsys.com/csharp/parameters.html

JS> I'm reading a book on C# and it says there are 4 ways of passing
JS> types:
JS>
JS> 1. Pass value type by value
JS> 2. Pass value type by reference
JS> 3. Pass reference by value
JS> 4. Pass reference by reference.
JS> My interpretation:
JS>
JS> 1. Essentially pushes the value type on the stack
JS> 2. Boxes the value type? pushes a pointer to the value type on the
JS> stack
JS> 3. since a reference is essentially a pointer we are pushing the
JS> pointer of
JS> the "reference"(object).
JS> 4. Boxing the reference type. Pushing a pointer to the reference
JS> type on the
JS> stack.
JS> so 1 is equivilent to 3 and 2 to 4 in the sense that the same idea
JS> is involved but just the context is different? 1 and 3 pushes the
JS> actual type's value while 2 and 4 push a pointer to the memory
JS> location of the value.
JS>
JS> Thanks,
JS> Jon
---
WBR,
Michael Nemtsev :: blog: http://spaces.live.com/laflour

"At times one remains faithful to a cause only because its opponents do not
cease to be insipid." (c) Friedrich Nietzsche
 
W

Willy Denoyette [MVP]

| I'm reading a book on C# and it says there are 4 ways of passing types:
|
| 1. Pass value type by value
| 2. Pass value type by reference
| 3. Pass reference by value
| 4. Pass reference by reference.
|
| My interpretation:
|
| 1. Essentially pushes the value type on the stack
| 2. Boxes the value type? pushes a pointer to the value type on the stack
| 3. since a reference is essentially a pointer we are pushing the pointer
of
| the "reference"(object).
| 4. Boxing the reference type. Pushing a pointer to the reference type on
the
| stack.
|
| so 1 is equivilent to 3 and 2 to 4 in the sense that the same idea is
| involved but just the context is different? 1 and 3 pushes the actual
type's
| value while 2 and 4 push a pointer to the memory location of the value.
|
| Thanks,
| Jon
|
|
1. Passes the value through a register(as per CLR calling convention) or the
stack.
Value --> register or stack --> callee.
2. Passes the "reference" to the boxed instance through a register or the
stack.
(Boxed)Object <--- reference ---> register or stack ---> callee
3. Passes the object's reference through a register or the stack.
Object <--- reference ---> register or stack ---> callee
4. Passes a pointer to the object reference through a register or the stack.
(no boxing done here!)
Object <--- reference <--- pointer ---> register or stack ---> callee

So, your interpretation is not correct, 1 and 3 are in no way equivalent, 1
is passing the actual value while 3 is passing it's reference. 2 and 4 are
not equivalent either, 2 passes a reference to the boxed value, while 4
passes a pointer to the reference to an object instance.
Only 2 and 3 are equivalent, or more precisely - they are the same.

Willy.
 
J

Jon Slaughter

Willy Denoyette said:
| I'm reading a book on C# and it says there are 4 ways of passing types:
|
| 1. Pass value type by value
| 2. Pass value type by reference
| 3. Pass reference by value
| 4. Pass reference by reference.
|
| My interpretation:
|
| 1. Essentially pushes the value type on the stack
| 2. Boxes the value type? pushes a pointer to the value type on the stack
| 3. since a reference is essentially a pointer we are pushing the pointer
of
| the "reference"(object).
| 4. Boxing the reference type. Pushing a pointer to the reference type on
the
| stack.
|
| so 1 is equivilent to 3 and 2 to 4 in the sense that the same idea is
| involved but just the context is different? 1 and 3 pushes the actual
type's
| value while 2 and 4 push a pointer to the memory location of the value.
|
| Thanks,
| Jon
|
|
1. Passes the value through a register(as per CLR calling convention) or
the
stack.
Value --> register or stack --> callee.
2. Passes the "reference" to the boxed instance through a register or the
stack.
(Boxed)Object <--- reference ---> register or stack ---> callee
3. Passes the object's reference through a register or the stack.
Object <--- reference ---> register or stack ---> callee
4. Passes a pointer to the object reference through a register or the
stack.
(no boxing done here!)
Object <--- reference <--- pointer ---> register or stack ---> callee

So, your interpretation is not correct, 1 and 3 are in no way equivalent,
1
is passing the actual value while 3 is passing it's reference. 2 and 4 are
not equivalent either, 2 passes a reference to the boxed value, while 4
passes a pointer to the reference to an object instance.
Only 2 and 3 are equivalent, or more precisely - they are the same.

on 1 we are passing a the value directly.
on 3 we are passing the value directly but it turns out its a reference type
so the value is really a reference. This is why they are equivilent. Because
they are both passed by value. The value itself is different but obviously
they are different in 2 and 4.

The difference between (1,3) compared (2,4) is that the thing put on the
stack(or register, I didn't know they allowed the use of register passing)
points to a value or is a value compared to it being a reference in (2,4).

i.e.

if you look at how I wrote it:

1. Pass value type by value
2. Pass value type by reference
3. Pass reference by value
4. Pass reference by reference.

I could have wrote it

1. Pass value type by value
3. Pass reference by value
2. Pass value type by reference
4. Pass reference by reference.

notice the endings... so they are in some way equivilent and not "in no
way".
 
W

Willy Denoyette [MVP]

|
| | >
| > | > | I'm reading a book on C# and it says there are 4 ways of passing
types:
| > |
| > | 1. Pass value type by value
| > | 2. Pass value type by reference
| > | 3. Pass reference by value
| > | 4. Pass reference by reference.
| > |
| > | My interpretation:
| > |
| > | 1. Essentially pushes the value type on the stack
| > | 2. Boxes the value type? pushes a pointer to the value type on the
stack
| > | 3. since a reference is essentially a pointer we are pushing the
pointer
| > of
| > | the "reference"(object).
| > | 4. Boxing the reference type. Pushing a pointer to the reference type
on
| > the
| > | stack.
| > |
| > | so 1 is equivilent to 3 and 2 to 4 in the sense that the same idea is
| > | involved but just the context is different? 1 and 3 pushes the actual
| > type's
| > | value while 2 and 4 push a pointer to the memory location of the
value.
| > |
| > | Thanks,
| > | Jon
| > |
| > |
| > 1. Passes the value through a register(as per CLR calling convention) or
| > the
| > stack.
| > Value --> register or stack --> callee.
| > 2. Passes the "reference" to the boxed instance through a register or
the
| > stack.
| > (Boxed)Object <--- reference ---> register or stack ---> callee
| > 3. Passes the object's reference through a register or the stack.
| > Object <--- reference ---> register or stack ---> callee
| > 4. Passes a pointer to the object reference through a register or the
| > stack.
| > (no boxing done here!)
| > Object <--- reference <--- pointer ---> register or stack ---> callee
| >
| > So, your interpretation is not correct, 1 and 3 are in no way
equivalent,
| > 1
| > is passing the actual value while 3 is passing it's reference. 2 and 4
are
| > not equivalent either, 2 passes a reference to the boxed value, while 4
| > passes a pointer to the reference to an object instance.
| > Only 2 and 3 are equivalent, or more precisely - they are the same.
| >
|
| on 1 we are passing a the value directly.
Yep, to be exact, you are passing a copy of the "value".
What's important here, is that the original value cannot be changed by the
callee, he can only change the value of the copy.


| on 3 we are passing the value directly but it turns out its a reference
type
| so the value is really a reference.

I don't know exactly what you mean with 'equivalent' but semantically they
are not, 3 is not passing the object's value it's passing a copy of the
reference to the object, that is, you are passing a reference which always
takes 4 bytes (or 8 bytes), what's important here, is that the callee has
access to the objects data, changes made by the callee are made to the one
and only object the reference is refering to (except for immutable object
types like 'String'). However, the callee cannot change the callers
reference value, and maybe that's why you call it equivalent with 1.

This is why they are equivilent. Because
| they are both passed by value. The value itself is different but obviously
| they are different in 2 and 4.
|
| The difference between (1,3) compared (2,4) is that the thing put on the
| stack(or register, I didn't know they allowed the use of register passing)
| points to a value or is a value compared to it being a reference in (2,4).
|

Not really, 4 is not passing a reference, it's passing a 'pointer' to a
reference. That means the callee can change both the original reference
value and the object's value the reference is refering to.


| i.e.
|
| if you look at how I wrote it:
|
| 1. Pass value type by value
| 2. Pass value type by reference
| 3. Pass reference by value
| 4. Pass reference by reference.
|
| I could have wrote it
|
| 1. Pass value type by value
Yep.
| 3. Pass reference by value
Yep.
| 2. Pass value type by reference

The 'value type' becomes a reference type after boxing, so what you pass is
a copy of the reference value, so in reality you pass a "reference by value"
just like 3.

| 4. Pass reference by reference.
|
Keep in mind that a reference in the CLR is tracked by the JIT while a
pointer is not. And in reality what's passed in 4 is a pointer pointing to
the reference, the reference value will change when the object moves in the
heap, but the pointer value will not because the reference location will
not.

(1) pointer --> (2)reference --> (3)object
value 2 will change when 3 moves, 1 does not change as the location of 2
does not change when 3 moves.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top