Out parameters and initialization

Regan Heath regan at netwin.co.nz
Sat Feb 25 20:30:09 PST 2006


On Sat, 25 Feb 2006 18:58:44 -0800, Unknown W. Brackets  
<unknown at simplemachines.org> wrote:
> If that is the meaning, some symbol should be used to indicate that  
> there is a reference being made.

The symbols 'inout' and 'out' indicate an alias/reference is being made.

> I don't think, personally, it makes any sense to say that in is a  
> replacement for what might be passed.  It is much more like an  
> initializer, which would never behave in that way.  To me, it is unclear  
> and unlike the rest of the language to do as you suggest.

I didn't mean to suggest that 'in' was a replacement for what is passed,  
but rather that the default initialiser is a replacement for what _isn't_  
passed.

> Your suggestion separates the logic of parameter defaulting from  
> initialization completely, but they share the same syntax (as they share  
> again with assignment.)  I think this is, at best, unclear and clumsy.  
> At worst, it is obviously inconsistent and confusing.

I think you make a valid point here. default parameters, and assignment  
(which initialization is essentially) share the same syntax, they both use  
'='. It does suggest that a default parameter is an initializer, when in  
fact, I believe it's not that at all. That same syntax, '=', is likely the  
cause of this thread :)

> But that is more of a philosophical debate, and that will be for Walter  
> to answer, ultimately.  My point is that there is a bug here,  
> nonetheless.

I agree, my idea at the solution is below.

> Regardless of what you are saying, why should my initial example  
> compile? should not compile, it shouldIt should either work as  
> initialization, or not compile.  It should not compile and do nothing.   
> This is also unclear and inconsistent.

Your first example compiles because you are passing a parameter to all  
calls of 'test' and therefore the default parameter is never used.  
However, this for example:

void test(out uint i = 5)
{
	assert(i == 5);
}

void main()
{
	uint i;
	test(i); //compiles
	test();  //cast(uint)5 is not an lvalue
}

Will not compile because the default parameter is required for the 2nd  
call to 'test' and '5' is not an lvalue (cannot be aliased).

The solution: I think it would be fair to ask for the compiler to error on:

   void test(out uint i = 5)

regardless of whether the default parameter is ever required, simply  
because it will never be legal to have a non lvalue default parameter to  
an 'out' or 'inout' parameter. At the same time perhaps this should remain  
valid:

uint globalVar;
void test(out uint i = globalVar) {}

because I can imagine some useful things you can do with this.

What do you think Walter?

Regan

> -[Unknown]
>
>
>> On Sat, 25 Feb 2006 16:21:23 -0800, Unknown W. Brackets  
>> <unknown at simplemachines.org> wrote:
>>> That does not make it logical or consistent.  It makes it confusing  
>>> and inconsistent.  Utility is not at all my concern.
>>  Ok, so lets look at the consistency of this.
>>
>>> In other words, you're essentially saying that this makes sense:
>>>
>>> var2 = 2;
>>> var1 = var2;
>>> var1 = 1;
>>> assert(var2 == 1);
>>  No, he's saying that this makes sense:
>>  void foo(inout int var1) { var1 = 1; }
>>  int var2 = 2;
>> foo(var2);
>> assert(var2 == 1);
>>  Remember, 'inout' aliases the variable you pass, the parameter 'var1'  
>> is another name for the variable 'var2'.
>>   So, when you write:
>>  void foo(inout int var1 = 7)
>>  what are you saying?
>>  Lets start with what a default parameters means, in this case:
>>  void foo(int var1 = 7) {}
>>  says, if I do not get passed a variable, pass 7, in other words:
>>  foo();
>>  is called as:
>>  foo(7);
>>  Agreed?
>>   Therefore:
>>  void foo(inout int var1 = 7)
>>  says, if I do not get passed a variable, pass 7, meaning:
>>  foo();
>>  is called as:
>>  foo(7);
>>  Agreed?
>>   Now, as well all know you cannot pass '7' as inout because you cannot  
>> alias '7'.
>>  What I am trying to show here is that default parameters are behaving  
>> both logically and consistently, they always mean: "If I do not get  
>> passed a variable, pass X" where X is the default parameter value  
>> supplied.
>>  Further, 'inout' is behaving both logically and consistently, in all  
>> cases it aliases the parameter which is passed.
>>   The behaviour of 'in'+'default parameter' is not the same as  
>> 'inout'+'default parameter' but why should it be? IMO one is an apple  
>> and the other an orange.
>>  Regan




More information about the Digitalmars-d-bugs mailing list