Thread overview
'out' parameters
Jul 21, 2004
Derek Parnell
Jul 21, 2004
kinghajj
Jul 21, 2004
Derek Parnell
Jul 21, 2004
Regan Heath
Jul 21, 2004
Andy Friesen
Re: 'out' parameters - it's a bug
July 21, 2004
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
July 21, 2004
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.


July 21, 2004
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


July 21, 2004
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
July 21, 2004
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/
July 21, 2004
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
July 21, 2004
walter confirmed it on the bug board.