Out parameters and initialization

Regan Heath regan at netwin.co.nz
Sun Feb 26 15:12:15 PST 2006


On Sun, 26 Feb 2006 14:44:57 -0800, Unknown W. Brackets  
<unknown at simplemachines.org> wrote:
> Yes, but this is a topic about a bug.  We are no longer really talking  
> about the bug.
>
> If you used your workaround, you would have:
>
> 1. Extra global variables somewhere in memory, which may not be  
> desirable.

True, however you can use the same default global for every parameter of  
the same type provided the 'out' contract of the function does not check  
them (which is something you will know and can work around), eg.

int dontCare;
int test(out int a = dontCare, out int b = dontCare, out int c = dontCare)  
{ ... }

You can do this because the dummy globals are never 'read' by anything at  
any time.

> 2. Uninitialized variables, from what I can tell (out parameters are  
> normally initialized to their default state at the beginning of the  
> function.) This may cause unexpected/hard-to-reproduce bugs.

'out' and dummy globals do not prevent the init of the out parameter:

import std.stdio;

int global = 5;

void test(out int a = global) {
   writefln(a);
}

void main()
{
	writefln(global);
	test();
}

Output:
5
0

> 3. Requirements to use synchronized blocks around accesses to the  
> variables

Why? Given that value of an 'out' variable is never 'read' by anyone at  
any time it does not matter what value it has at any given time, or even  
that it has any sensible value at all.

The same cannot be said for 'inout' however. For 'inout' you would need to  
protect access to the global. For 'inout' your points above are valid. You  
would need to protect access to the global, but, as Ivan mentioned that  
may be exactly what you want.

In the end are we arguing about the utility of each set of behaviour or  
the logic of it?

If we're arguing about the logic, my opinion remains that the current  
behaviour is logical given the following rules:
   "out and inout _always_ alias/reference the parameter passed"
   "a default parameter is passed when no parameter is given explicitly"
   "a constant cannot be passed by reference"

In order to implement inout how you describe (as 'in' sometimes) you'd  
need to break rule #1, making the behaviour illogical and inconsistent  
with other instances of 'inout'.

The problem seems mainly to be the perception that a default parameter is  
a default initializer and that is simply incorrect in the general case. It  
is only true for value types passed as 'in' parameters. Take for example:

void test(int* a = 5) {} //cannot implicitly convert expression (5) of  
type int to int*

you would never expect that to work, right?

This is essentially identical to:

void test(inout int a = 5) {}

Regan



More information about the Digitalmars-d-bugs mailing list