Discarded return values

Simen Kjærås simen.kjaras at gmail.com
Tue Jan 30 16:42:39 UTC 2018


On Tuesday, 30 January 2018 at 14:01:00 UTC, bauss wrote:
> unittest {
>     auto a = foo();          // This should fail, because a is 
> never used.

No it shouldn't. It is assigned to a variable, as the constraint 
said.


>     // This should also fail, because b is never used actually 
> used afterwards.
>     auto b = foo()
>     b.morph();

No it shouldn't. It is assigned to a variable, as the constraint 
said.


>    // This should fail, because d does not use c.
>    // A simply analysis of d will not work, you'll have to 
> track all passed values to d and whether they themselves should 
> be tracked with the attribute.
>    auto c = foo();
>    d(c);

No it shouldn't. It is assigned to a variable, as the constraint 
said.


>   // Same as above, should fail too since d doesn't use the 
> return value
>   d(foo());

No it shouldn't. It is passed to a function, as the constraint 
said.


> }
>
> The above is going to be very complex to implement in the 
> compiler.
>
> Sure a simple check if it has just been assigned to a variable 
> would work fine, but in the reality people would most likely 
> just do something like this then:
>
> auto unused = foo();
>
> And there ... we "hacked" our way around the attribute.

Yes, that's the point. Now it's visible that you're discarding 
the result.

The point isn't actually to make sure people keep the variable 
around - that'd be silly - it's to inform the programmer that 
potentially important information is discarded, and to stop the 
programmer from calling mutating functions on a temporary return 
value where it will have no effect.

For pure functions, this gives a warning:

auto fun() pure { return 3; }

unittest {
     fun(); // calling without side effects discards return value
}

Does that in any way whatsoever stop me from assigning the return 
value to a variable and then ignoring it? No. But doing so would 
make me an idiot. The compiler suggests I cast it to void if I 
really intended to discard the result. The reason for this is 
cast(void) is relatively easy to grep for, and sticks out like a 
sore thumb when looking through the code.


> So for it to work it has to track every single return value 
> from a function that implements the attribute and that is 
> borderline impossible to get correct.

No it's not. It's *perfectly* impossible the way your scheme 
works. What does this function do to its parameters?

extern(C) void foo(S s);

In other words, your idea of perfectly tracking how a value is 
used cannot be implemented at all. Trying to equate that with 
what I'm asking is disingenuous.

--
   Simen


More information about the Digitalmars-d-learn mailing list