digitalmars.D.learn - out contract misunderstanding (was: I cannot understand problem with
- mrd (24/24) Sep 18 2013 (new topic because old is mired in a long and clumsy source code)
- Ivan Kazmenko (8/12) Sep 18 2013 Why should it be? value is a mutable argument, and the out
- monarch_dodra (13/26) Sep 19 2013 I actually asked about this on the main threads:
- Ivan Kazmenko (9/24) Sep 19 2013 That doesn't seem to be possible in every case. For example,
- Artur Skawina (16/27) Sep 19 2013 In general, the problem is with accessing the argument at all, it
- mrd (4/14) Sep 19 2013 Why? it seems the documentation does not say anything about it.
(new topic because old is mired in a long and clumsy source code) ============ import std.stdio; static ubyte func( ulong value ) out( arr ) { writeln( "out contract, value=", value ); } body { writeln( "body, value=", value ); ubyte res; value >>= 7; return res; } void main() { func( 2 ); } ============ $ ./bug body, value=2 out contract, value=0 Why argument "value" in contract isn't equal 2 ?
Sep 18 2013
On Thursday, 19 September 2013 at 01:41:15 UTC, mrd wrote:$ ./bug body, value=2 out contract, value=0 Why argument "value" in contract isn't equal 2 ?Why should it be? value is a mutable argument, and the out contract evaluates it at the return point, which is after it's set to 0. It is no different than using value in the body just before the return point. If you want to preserve the original arguments until the return point, use const and create a mutable duplicate. Ivan Kazmenko.
Sep 18 2013
On Thursday, 19 September 2013 at 06:39:09 UTC, Ivan Kazmenko wrote:On Thursday, 19 September 2013 at 01:41:15 UTC, mrd wrote:I actually asked about this on the main threads: http://forum.dlang.org/thread/gdmwjyrefhreghznbibg forum.dlang.org I actually disagree though: How the function is implemented should have no bearing on how the output contract should be implemented. Both should get their own copy of the args. The implementation of a function should not have to create a local duplicate just because it happens to know that it has an out contract. This is particularly relent since (in theory), an in/out contract should appear in a function's interface, and compiled/called by client code (though that's not the case today).$ ./bug body, value=2 out contract, value=0 Why argument "value" in contract isn't equal 2 ?Why should it be? value is a mutable argument, and the out contract evaluates it at the return point, which is after it's set to 0. It is no different than using value in the body just before the return point. If you want to preserve the original arguments until the return point, use const and create a mutable duplicate. Ivan Kazmenko.
Sep 19 2013
On Thursday, 19 September 2013 at 07:45:44 UTC, monarch_dodra wrote:On Thursday, 19 September 2013 at 06:39:09 UTC, Ivan Kazmenko wrote:That doesn't seem to be possible in every case. For example, what if an argument is a class with copy constructor disabled? I'm not claiming that the current behavior is the best one. I just don't get a coherent picture of how it could be defined otherwise. And the current definition seems to follow the principle of least surprise for me. Ivan Kazmenko.On Thursday, 19 September 2013 at 01:41:15 UTC, mrd wrote:I actually disagree though: How the function is implemented should have no bearing on how the output contract should be implemented. Both should get their own copy of the args. The implementation of a function should not have to create a local duplicate just because it happens to know that it has an out contract. This is particularly relent since (in theory), an in/out contract should appear in a function's interface, and compiled/called by client code (though that's not the case today).Why argument "value" in contract isn't equal 2 ?Why should it be? <snip>
Sep 19 2013
On 09/19/13 20:01, Ivan Kazmenko wrote:On Thursday, 19 September 2013 at 07:45:44 UTC, monarch_dodra wrote:In general, the problem is with accessing the argument at all, it could indeed be uncopyable, but it could also be invalid /after/ the body of the function is executed. Eg void f(ref S s) out { assert(s.x==42); } body { free(&s); } Anything that either invalidates or moves ownership can easily result in invalid accesses. Variations on this could use pointers, classes, s/free/send/, refcounts etc (and having to always clear every stale ref isn't a practical solution).On Thursday, 19 September 2013 at 06:39:09 UTC, Ivan Kazmenko wrote:That doesn't seem to be possible in every case. For example, what if an argument is a class with copy constructor disabled?On Thursday, 19 September 2013 at 01:41:15 UTC, mrd wrote:I actually disagree though: How the function is implemented should have no bearing on how the output contract should be implemented. Both should get their own copy of the args. The implementation of a function should not have to create a local duplicate just because it happens to know that it has an out contract. This is particularly relent since (in theory), an in/out contract should appear in a function's interface, and compiled/called by client code (though that's not the case today).Why argument "value" in contract isn't equal 2 ?Why should it be? <snip>I'm not claiming that the current behavior is the best one. I just don't get a coherent picture of how it could be defined otherwise. And the current definition seems to follow the principle of least surprise for me.out-contracts shouldn't have access to the input args by default; that is something that should be explicitly requested. Some syntax sugar, for the cases when it actually is needed, could be nice, yes. But it's not how D currently defines out contracts, so that would be a larger change than just fixing the leak (which isn't a big problem in itself, the implications of speccing it like that would be). artur
Sep 19 2013
On Thursday, 19 September 2013 at 06:39:09 UTC, Ivan Kazmenko wrote:On Thursday, 19 September 2013 at 01:41:15 UTC, mrd wrote:Why? it seems the documentation does not say anything about it. Using variables values from another {} block is confusing.$ ./bug body, value=2 out contract, value=0 Why argument "value" in contract isn't equal 2 ?Why should it be? value is a mutable argument, and the out contract evaluates it at the return point, which is after it's set to 0. It is no different than using value in the body just before the return point.
Sep 19 2013