in

ASP.NET Weblogs

J e r o e n ' s   w e b l o g

Output parameters and the out modifier

Yesterday I was working on finishing an interface assembly in C# for one of my projects. When thinking about making the interfaces define exactly what I want them to I decided to look into the parameter types, checking to make sure I understood the semantics.

What struck me as odd, is that parameters declared with the out modifier are considered initially unassigned within a function member. This means that the following code:

void SomeMethod(out string str)
{
  Console.WriteLine(str);
}

has the compiler tell you: "error CS0165: Use of unassigned local variable 'str'". The funny thing is though, that if you change the offending line to assign something to str so it compiles (out requires you to assign something to the declared parameter before returning) and put a breakpoint on it, you'll see that the compiler does assign the parameter, it just doesn't allow you to use it before assigning something to it yourself. And yes, this is fully compliant with the defined semantics.

What I wonder though, is why are out parameters considered initially unassigned? It's not a strange scenario where you want to define a parameter that for instance returns the type of a conversion and may initially contain a requested type to convert to. If you don't pass anything you get default conversion (and a specification of what was picked in the output parameter).

If you declare such a parameter without any modifier and it's a reference type, you won't be able to assign something new to it since that won't be returned. Declaring it with the ref modifier forces you to always supply something in advance, which means you need to define what value denotes "no value supplied". And finally, declaring it with the out modifier means you'll be able to supply an input value but the callee will never be able to use it.

My conclusion: the language designers probably want to force me out of using parameters this way.

Published May 11 2004, 08:54 AM by jvdbos
Filed under:

Comments

 

Jerry Pisk said:

Isn't null supposed to denote "no value supplied"? For reference types anyways...
May 11, 2004 3:43 AM
 

Frans Bouma said:

Like with Sql parameters: out means out, not in. Some people define parameters as inout, supplying a value with the parameter and also want to retrieve a value with the same parameter. I think that's a reason for using ref. if you require an 'out' parameter to have a value, use ref or use another parameter for the input.

I find 'out' a weird keyword anyway. 'ref' is there to alter variables by a method, however 'out' is a keyword only required because some person cooked up the limitation of 1 return value per method. Instead of fixing that limitation (as it is done in Eiffel f.e.), they introduce 'out'.
May 11, 2004 3:48 AM
 

Jeroen said:

Jerry: I agree that for reference types, null is the default for not supplying an input. For value types however, it's less obvious.

Frans: Out does have something cool: the requirement of the callee to assign the parameter. I wish you could force this on ref types (but then you'd have the inout you mention :))
May 11, 2004 4:05 AM
 

C. van Berkel said:

Parameters with the keyword "out" should be used as an alternative to returning a value.
In the case you want to "return" 2 values. It's not possible to use return.

This is the reason the compiler doesn't allow branching out of the method, when you haven't assign it yet. (To ensure the calling code can't use the "unassigned" parameter.

May 11, 2004 4:22 AM
 

Jeroen said:

I'm probably just too used to those methods in the Win32 API where you have to provide a pointer to an int, where the int contains the size of your buffer and the method uses it to return how many bytes were written to it.

I remember those constructs being just about everywhere (for instance when dealing with the registry: RegQueryValue).
May 11, 2004 5:32 AM
 

Raymond Chen said:

If it's in/out then the parameter type is "ref". Your complaint about "ref" is "But then what if I don't want to pass something in?" Of course you have the same problem with in/out: How do you know whether the "in" is a genuine "in" or a "no really I don't want to pass something in"? Whatever mechanism you use for in/out, you can use for ref.
May 11, 2004 11:26 AM
 

Jeroen said:

Ref it is!

Raymond: I wasn't really complaining btw. I was just surprised to see that the "input" is there in the debugger (which makes sense ofcourse because it's a reference after all) but that the code can't touch it. Forcing a method to assign something to an out parameter is pretty cool for interfaces, so I was hoping to use it in a ref-kind-of-way :)
May 11, 2004 1:42 PM

Leave a Comment

(required)  
(optional)
(required)  
Add