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