When in doubt - write code - but ...

  • Thread starter Thread starter Sahil Malik
  • Start date Start date
S

Sahil Malik

So I have always been told - when in doubt - write it out and run it and see
for yourself what happens.

But someone recently told me that if I have a value type and I pass it
byref, it will always box/unbox it. How do I find the truth?

- Sahil Malik
http://dotnetjunkies.com/weblog/sahilmalik
 
Sahil Malik said:
So I have always been told - when in doubt - write it out and run it and
see
for yourself what happens.

But someone recently told me that if I have a value type and I pass it
byref, it will always box/unbox it. How do I find the truth?

No, passing it as an object results in a box, passing it via ref or out
results in the stack address being passed(ldloca instruction)
 
Sahil Malik said:
So I have always been told - when in doubt - write it out and run it and
see
for yourself what happens.

But someone recently told me that if I have a value type and I pass it
byref, it will always box/unbox it. How do I find the truth?

I think you're asking whether the value is passed by reference or by copy-in
copy-out. If so, you can prove it's the former with a program that passes a
field by reference.

using System;

class Pass {
int i;

public static void Main() {
Pass p = new Pass();
p.i = 0;
TryIt(p, ref p.i);
}

static void TryIt(Pass p, ref int i) {
i = 12;
if (p.i == 0)
Console.WriteLine("copy in-out");
else if (p.i == 12)
Console.WriteLine("reference");
else
Console.WriteLine("No idea: " + p.i);
}
}

As you'll see if you run it, the answer is "reference".
 
Mike ,

OP is asking how "value types" allocated on the stack are passed.
In you sample you ain't passing any stack allocated type, p.i is on the
heap.

Willy.
 
Mike Schilling said:
I think you're asking whether the value is passed by reference or by copy-in
copy-out. If so, you can prove it's the former with a program that passes a
field by reference.

Note (if you're interested in VB.NET :) that when passing a property by
reference or (IIRC) passing a variable of different type by reference
(with option strict off) that that *does* have copy-in copy-out
semantics. How many developers that's clear to is another matter!
 
Willy Denoyette said:
Mike ,

OP is asking how "value types" allocated on the stack are passed.
In you sample you ain't passing any stack allocated type, p.i is on the
heap.

I'd assume, in the absence of any other evidence, that there's only one
mechanism for passing a value type by reference.
 
Jon Skeet said:
Note (if you're interested in VB.NET :) that when passing a property by
reference or (IIRC) passing a variable of different type by reference
(with option strict off) that that *does* have copy-in copy-out
semantics.

Which makes prefect sense; in both cases there's no value of the proper type
to create a reference to.
How many developers that's clear to is another matter!

It's a pretty fine distinction and matters close to 0% of the time, I
suspect. I used to work on a 4GL that distinguished between byref and
inout; that probably confused far more people than it enlightened.
 
Sorry, if I wasn't clear. OP asks about a value type on the stack, your
sample passes a value type on the heap (it's embedded in a heap allocated
reference type).

Here is a sample that puts a value type on the stack and call a method
passing the location on the stack to the caller. In reality nothing is
passed at all, the JIT compiler generates code to directly access the stack
location(s) in the callee.

struct MyStruct
{
public int i;
public byte b;
}
class Tester
{
static void Main()
{
MyStruct ms = new MyStruct(); // ms is on the stack (the actual values of
i and b)
ms.i=255;
ms.b=0x0a;
PassByRefVal(ref ms);
....
}
static void PassByRefVal(ref MyStruct val)
{
val.i = 254; // change value on the stack
}

}

Willy.
 
Willy Denoyette said:
Sorry, if I wasn't clear. OP asks about a value type on the stack, your
sample passes a value type on the heap (it's embedded in a heap allocated
reference type).

Yes, I get it. I was demonstrating that a value type passed "ref" really is
passed by reference, not by copy-in copy-out. It's true that my example was
a value type on the heap, but it would make no sense for the two cases
(value type on the heap, value type on the stack) to use different
parameter-passing conventions.
 
Back
Top