“Out” parameters and destructors
Salih Dincer
salihdb at hotmail.com
Fri Mar 21 04:23:58 UTC 2025
On Saturday, 15 March 2025 at 11:44:14 UTC, Ogi wrote:
> On Friday, 14 March 2025 at 16:54:10 UTC, Ali Çehreli wrote:
>> Although understandably undesirable, this is according to spec:
>>
>> https://dlang.org/spec/function.html#ref-params
>>
>> "An out parameter [...] is initialized with x.init upon
>> function invocation."
>
> I want to clarify if this is intentional or not, and what is
> the intention if it is. Currently, it turns out that the
> variable has to be destroyed before passing it as an “out”
> argument. It’s counter-intuitive, and it defeats the purpose of
> “out” parameters.
>
I think you're exaggerating the issue more than it is! Who is
going to use a local variable in their code? Let's look at the
issue like this:
```d
enum check = 40;
struct S
{
int num = check;
auto inc2() => num += 2;
}
void foo(out S s)
in (s.num == check)
{
assert(s.num == check);
}
import std.stdio;
void main()
{
S s;
s.foo();
s.inc2();
s.num.writeln; // 42
void bar(out S s)
in (s.num == check)
{
assert(s.num == check);
}
bar(s);
s.num.writeln; // 40
}
```
The issue arises in the bar(s); call. Although s.num was
incremented to 42 before bar(s), the out parameter in D resets s
to its default state before entering bar(). Since s.num is
initialized to check (which is 40), the assertion inside bar()
holds, and after the function call, s.num is reset to 40. This
explains why s.num.writeln; prints 40 after bar(s), effectively
discarding the previous increment.
SDB at 79
More information about the Digitalmars-d
mailing list