www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - 'out' parameters

reply Derek Parnell <derek psych.ward> writes:
Is an 'out' parameter supposed to be set to .init at the time the function
is entered or when it exits? 

In other words, is an 'out' parameter effectively a write-only argument. If
it's initialized when a function is entered, then it will *always* be a
known value regardless of what value is actually passed to the function.

If its initialized at function exit, I assume that would only occur if it
wasn't explicitly assigned to during the function execution. This would
mean you could use its passed value (read it) but if you never set in the
function, it would be set to .init automatically.

(I know there is a current bug report re that it doesn't initialize it at
all in v0.95). 

<code>
 void foo(out int bar)
 {
    printf("In  Foo %d\n", bar);
 }

 void main()
 {
    int x = 3;
    foo(x);
    printf("Out Foo %d\n", x);
 }
</code>

The output is ...

 c:\temp>test
 In  Foo 3
 Out Foo 3

If it was initialized on entrace I'd expect the output to be ...

 In  Foo 0
 Out Foo 0

If it was initialized on exit I'd expect the output to be ...

 In  Foo 3
 Out Foo 0

-- 
Derek
Melbourne, Australia
21/Jul/04 10:23:41 AM
Jul 20 2004
next sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
it's supposed to be initialized on entry (initialized on exit wouldn't make
much sense now would it ;) after all it's "out" ).  but i could have sworn
this worked before..

in fact, i took the "out" example from the D documents, and it doesn't work
as it's supposed to..!  this isn't good.
Jul 20 2004
prev sibling next sibling parent reply kinghajj <kinghajj_member pathlink.com> writes:
As far as I know, 'out' is just another way of doing what pointers can do.

Example:

<code>
void foo(out int x)
{
x = 2;
}

int main()
{
int x = 102;
printf("Before foo(): %i", x);
foo(x);
printf("After foo(): %i", x);
return x;
}
</code>

Produces:
Before foo(): 102
After foo(): 2

So, the 'x' in foo is never initialized: it takes the value of the argument
(like all arguments should!). Then, after foo() is done, the 'x' in main()
(which was used to give the argument to foo()) is changed to foo()'s x. "out int
x" is just like "int *x", but without the complexity of pointers.

In article <cdkdrc$22qd$1 digitaldaemon.com>, Derek Parnell says...
Is an 'out' parameter supposed to be set to .init at the time the function
is entered or when it exits? 

In other words, is an 'out' parameter effectively a write-only argument. If
it's initialized when a function is entered, then it will *always* be a
known value regardless of what value is actually passed to the function.

If its initialized at function exit, I assume that would only occur if it
wasn't explicitly assigned to during the function execution. This would
mean you could use its passed value (read it) but if you never set in the
function, it would be set to .init automatically.

(I know there is a current bug report re that it doesn't initialize it at
all in v0.95). 

<code>
 void foo(out int bar)
 {
    printf("In  Foo %d\n", bar);
 }

 void main()
 {
    int x = 3;
    foo(x);
    printf("Out Foo %d\n", x);
 }
</code>

The output is ...

 c:\temp>test
 In  Foo 3
 Out Foo 3

If it was initialized on entrace I'd expect the output to be ...

 In  Foo 0
 Out Foo 0

If it was initialized on exit I'd expect the output to be ...

 In  Foo 3
 Out Foo 0

-- 
Derek
Melbourne, Australia
21/Jul/04 10:23:41 AM

Jul 20 2004
parent reply Derek Parnell <derek psych.ward> writes:
On Wed, 21 Jul 2004 02:23:06 +0000 (UTC), kinghajj wrote:

 As far as I know, 'out' is just another way of doing what pointers can do.

Well, it seems from the docs, that its more than that. Sure it causes the value to be passed by reference (like a pointer to it), but it is also supposed to initialize its value too. This is different to an 'inout' argument which is just a pass-by-reference value without any initialization. The difference is that 'out' parameters should always contain the .init value when your function starts running but 'inout' parameters contain whatever value is passed to your function. But this is the heart of my question. Or to put it another way, if the function is (very contrived so bear with me) .... void foo(out int x) { if (x <= 0) {funcA(); x = 1}; if ((x == -2) || (x == 2)) {funcB(); x = 1}; } and I use it thus ... int t; t = -2; foo(t); Will funcA() get called? Will funcB() get called? Because if 'x' is initialized prior to foo() running, funcA() will be called and funcB() will not be called. If 'x' is not initialized prior to foo() running, funcA() will be called and so will funcB(). And gven ... int t; t = 2; foo(t); What happens now? If 'x' is initialized prior to foo() running, funcA() will be called and funcB() will not be called. If 'x' is not initialized prior to foo() running, funcA() will be not be called and funcB() will be called. The other possibility is that the 'x' is set to .init when the function leaves, if and only if your function *never* explicitly sets it to anything. This would allow the function to use the value as passed, and have the funciotn automatically 'reset' it to .init when it finishes. -- Derek Melbourne, Australia 21/Jul/04 12:47:18 PM
Jul 20 2004
parent Regan Heath <regan netwin.co.nz> writes:
They should be initialised before your function starts. If you want to 
read it _and_ set it 'inout' is what you want. I believe there is a bug in 
DMD 0.95.

On Wed, 21 Jul 2004 13:05:10 +1000, Derek Parnell <derek psych.ward> wrote:

 On Wed, 21 Jul 2004 02:23:06 +0000 (UTC), kinghajj wrote:

 As far as I know, 'out' is just another way of doing what pointers can 
 do.

Well, it seems from the docs, that its more than that. Sure it causes the value to be passed by reference (like a pointer to it), but it is also supposed to initialize its value too. This is different to an 'inout' argument which is just a pass-by-reference value without any initialization. The difference is that 'out' parameters should always contain the .init value when your function starts running but 'inout' parameters contain whatever value is passed to your function. But this is the heart of my question. Or to put it another way, if the function is (very contrived so bear with me) .... void foo(out int x) { if (x <= 0) {funcA(); x = 1}; if ((x == -2) || (x == 2)) {funcB(); x = 1}; } and I use it thus ... int t; t = -2; foo(t); Will funcA() get called? Will funcB() get called? Because if 'x' is initialized prior to foo() running, funcA() will be called and funcB() will not be called. If 'x' is not initialized prior to foo() running, funcA() will be called and so will funcB(). And gven ... int t; t = 2; foo(t); What happens now? If 'x' is initialized prior to foo() running, funcA() will be called and funcB() will not be called. If 'x' is not initialized prior to foo() running, funcA() will be not be called and funcB() will be called. The other possibility is that the 'x' is set to .init when the function leaves, if and only if your function *never* explicitly sets it to anything. This would allow the function to use the value as passed, and have the funciotn automatically 'reset' it to .init when it finishes.

-- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jul 20 2004
prev sibling next sibling parent Andy Friesen <andy ikagames.com> writes:
Derek Parnell wrote:

 Is an 'out' parameter supposed to be set to .init at the time the function
 is entered or when it exits? 
 
 In other words, is an 'out' parameter effectively a write-only argument. If
 it's initialized when a function is entered, then it will *always* be a
 known value regardless of what value is actually passed to the function.
 
 If its initialized at function exit, I assume that would only occur if it
 wasn't explicitly assigned to during the function execution. This would
 mean you could use its passed value (read it) but if you never set in the
 function, it would be set to .init automatically.

You should be seeing two 0s. The idea is that an 'out' parameter is one which recieves a value from the function, but does not send one. -- andy
Jul 20 2004
prev sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
walter confirmed it on the bug board.
Jul 21 2004