Why do I get a

G

Guest

Mr. Gunnerson, et. al.

Why does the C# compiler keep on complaining about an "out" parameter that is not assigned when it is really is? Here is the snippet.

using System

namespace BugNam

class Bu

public static Bug Instance = new Bug()
public Bug(){} // cto
static int Main(String[] args) // not voi

int iResultM = 0
Instance.MyIncrementer(out iResultM)
return iResultM
} // end Mai
public void MyIncrementer(out int iArgNum

// iArgNum = 0; // uncomment this and the error goes awa
iArgNum = iArgNum + 1; // causes an error!!!

}


If I uncomment the iArgNum = 0 line, the error goes away

Is this a compiler bug or my bug? After reading the online help, I don't see what I am doing wrong. Notice the original argument was declared as a local variable and was initialized as well (to 0). Then it was passed as an out parameter -- in other words I'm initializing it because I know the function MyIncrementer will be trying to read it before it sets it (and to boot, I didn't even have to use out since out can be used for a variable without initializing it)

What's up

Thanks

Harr
 
B

Bjorn Abelli

Mr. Gunnerson, et. al.:
Why does the C# compiler keep on complaining about
an "out" parameter that is not assigned when it is
really is?

It's not assigned *within* the method. There's a big difference between
"ref" and "out".


[snip]

int iResultM = 0;
Instance.MyIncrementer(out iResultM);

public void MyIncrementer(out int iArgNum)
{
// iArgNum = 0; // uncomment this and the error goes away
iArgNum = iArgNum + 1; // causes an error!!!!
}

[snip]
If I uncomment the iArgNum = 0 line, the error goes away.

"out" means that the parameter/variable is "returned" from the method, and
whatever value you have assigned to it outside and before the call, is
ignored. That variable is just "the place" where the result then is put
into.

In the line

iArgNum = iArgNum + 1;

....you're consequencually trying to "use" the variable without it having
been initialized.

// Bjorn A
 
G

Guest

I didn't see this on MSDN but in the Anders H. book I see the statement:

"Within a method, just like a local variable, an output variable is considered initially unassigned and must be "definitely" assigned before it's value is used.

This explains my error and why assigning to 0 (of no use to me) cleared it up -- I see now that the language designers are intending for this to be used for functions that return multiple values. This means I am forced to pass the same parameter as both an input and (separately) an "out" parameter to achieve my desired results. I don't have the compiler in front of me but hopefully I can do something like:

Instance.MyIncrementer(iResultM, out iResultM);

public void MyIncrementer(int iArgNumInput, out int iArgNum)
{
iArgNum = iArgNumInput;
iArgNum = iArgNum + 1;
}


So C# truly has eliminated "pass by reference" in that one can't read the value of the "out" parameter -- one must set it first. I wonder if this is a design flaw or if this is intentional or perhaps it is necessary to support the language. I suppose the storage in the callee is initialized AFTER (or just at) return from the function -- and as well, the JIT compiler probably cannot easily tell if all call sites have intialized the the memory -- the JIT can tell the function initialized it so therefore on the way back, the callee will have a definite value to store in the possibly uninitialized parameter varaible.

I thank myself for answering my own question :) :)

I think MSDN on-line help should state that point more loudly anc clearly (repeating): "Within a method, just like a local variable, an output variable is considered initially unassigned and must be "definitely" assigned before it's value is used.
 
B

Bjorn Abelli

...
public void MyIncrementer(int iArgNumInput, out int iArgNum)
{
iArgNum = iArgNumInput;
iArgNum = iArgNum + 1;
}
So C# truly has eliminated "pass by reference" in that one
can't read the value of the "out" parameter -- one must set
it first.

Why don't you use "ref" instead, if that's what you want?

public void MyIncrementer(ref int iArgNum)
{
iArgNum = iArgNum + 1;
}

// Bjorn A
 
J

John Baro

public void NotInit()
{
int i;
MyIncrementer(out i);
}
In this case i has not been initialised and as such needs to be initialised.

You should be passing by ref if you are going to use the parameters existing
value in the method (which you are in this case).

On a style note (not important but c# has such cool style) this looks better
:)

public void MyIncrementer(ref NumToIncrement)
{
NumToIncrement += 1;
}

HTH
JB

Harry said:
Mr. Gunnerson, et. al.:

Why does the C# compiler keep on complaining about an "out" parameter that
is not assigned when it is really is? Here is the snippet.:
using System;

namespace BugName
{
class Bug
{
public static Bug Instance = new Bug();
public Bug(){} // ctor
static int Main(String[] args) // not void
{
int iResultM = 0;
Instance.MyIncrementer(out iResultM);
return iResultM;
} // end Main
public void MyIncrementer(out int iArgNum)
{
// iArgNum = 0; // uncomment this and the error goes away
iArgNum = iArgNum + 1; // causes an error!!!!
}
};
}

If I uncomment the iArgNum = 0 line, the error goes away.

Is this a compiler bug or my bug? After reading the online help, I don't
see what I am doing wrong. Notice the original argument was declared as a
local variable and was initialized as well (to 0). Then it was passed as an
out parameter -- in other words I'm initializing it because I know the
function MyIncrementer will be trying to read it before it sets it (and to
boot, I didn't even have to use out since out can be used for a variable
without initializing it).
 
J

John Baro

Paul E Collins said:
John Baro said:
On a style note (not important but c# has such cool
style) this looks better :)
[...]
NumToIncrement += 1;

NumToIncrement++;

That too.
Personally I use NumToIncrement++; so I dont know why I wrote NumToIncrement
+= 1;
However if you wanted to add two you would do NumToIncrement += 2; (Not that
we want to do this however)
:)
Cheers
JB
 

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