www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - out contract misunderstanding (was: I cannot understand problem with

reply "mrd" <denis.feklushkin gmail.com> writes:
(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
parent reply "Ivan Kazmenko" <gassa mail.ru> writes:
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
next sibling parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
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:
 $ ./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.
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).
Sep 19 2013
parent reply "Ivan Kazmenko" <gassa mail.ru> writes:
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:
 On Thursday, 19 September 2013 at 01:41:15 UTC, mrd wrote:
 Why argument "value" in contract isn't equal 2 ?
Why should it be? <snip>
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).
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.
Sep 19 2013
parent Artur Skawina <art.08.09 gmail.com> writes:
On 09/19/13 20:01, Ivan Kazmenko wrote:
 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:
 On Thursday, 19 September 2013 at 01:41:15 UTC, mrd wrote:
 Why argument "value" in contract isn't equal 2 ?
Why should it be? <snip>
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).
That doesn't seem to be possible in every case. For example, what if an argument is a class with copy constructor disabled?
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).
 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
prev sibling parent "mrd" <denis.feklushkin gmail.com> writes:
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:
 $ ./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.
Why? it seems the documentation does not say anything about it. Using variables values from another {} block is confusing.
Sep 19 2013