www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - DBC problem..

reply Regan Heath <regan netwin.co.nz> writes:
Ok,

So I wrote an MD5 implementation before realising std.md5 existed (when 
did that happen?). I think it was good for me, I can compare what I came 
up with with std.md5 and see where I didn't quite "do the D thing" :)

Tho.. I also think the std.md5 implementation does not follow some of the 
Style Guide :)

One thing I came across while doing it was, a "Stack Overflow" due to 
having ...

uint[] decode(char[] block)
in {
}
out (result) {
	//assert(encode(result) == block);
}		
body {
	uint[] result;
	uint i;
	
	result.length = block.length/4;
	for (i = 0; i < block.length; i += 4) {
		result[i/4] = block[i] | (block[i+1] << 8) | (block[i+2] << 16) | 
(block[i+3] << 24);
	}
		
	return result;
}

char[] encode(uint[] value)
in {
}
out (result) {
	//assert(decode(result) == value);
}
body{
	char[] result;
	uint i;
	
	result.length = value.length*4;
	for(i = 0; i < result.length; i += 4) {
		result[i] = value[i/4] & 0xff;
		result[i+1] = (value[i/4] >> 8) & 0xff;
		result[i+2] = (value[i/4] >> 16) & 0xff;
		result[i+3] = (value[i/4] >> 24) & 0xff;
	}

	return result;
}

NOTE the commented assert lines, uncommenting them causes decode to call 
encode to call decode to call encode ...

It must be my lack of imagination but how do I get round this?

Or.. is this a bug?

Should DBC blocks be processed for functions used within DBC blocks? or 
not?

Regan.

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jun 07 2004
parent reply Regan Heath <regan netwin.co.nz> writes:
No-one?

How do I solve this, do people think this is a bug in the design of DBC...

Basically you cannot have a pair of functions test each other, this is 
desirable for any encode/decode pair, eg.

char[] encode(char[] source)
in {
}
out (result) {
	assert(decode(result)==source);
}
body {
}

char[] decode(char[] source)
in {
}
out (result) {
	assert(encode(result)==source);
}
body {
}

On Mon, 07 Jun 2004 23:16:50 +1200, Regan Heath <regan netwin.co.nz> wrote:

 Ok,

 So I wrote an MD5 implementation before realising std.md5 existed (when 
 did that happen?). I think it was good for me, I can compare what I came 
 up with with std.md5 and see where I didn't quite "do the D thing" :)

 Tho.. I also think the std.md5 implementation does not follow some of 
 the Style Guide :)

 One thing I came across while doing it was, a "Stack Overflow" due to 
 having ...

 uint[] decode(char[] block)
 in {
 }
 out (result) {
 	//assert(encode(result) == block);
 }		
 body {
 	uint[] result;
 	uint i;
 	
 	result.length = block.length/4;
 	for (i = 0; i < block.length; i += 4) {
 		result[i/4] = block[i] | (block[i+1] << 8) | (block[i+2] << 16) | 
 (block[i+3] << 24);
 	}
 		
 	return result;
 }

 char[] encode(uint[] value)
 in {
 }
 out (result) {
 	//assert(decode(result) == value);
 }
 body{
 	char[] result;
 	uint i;
 	
 	result.length = value.length*4;
 	for(i = 0; i < result.length; i += 4) {
 		result[i] = value[i/4] & 0xff;
 		result[i+1] = (value[i/4] >> 8) & 0xff;
 		result[i+2] = (value[i/4] >> 16) & 0xff;
 		result[i+3] = (value[i/4] >> 24) & 0xff;
 	}

 	return result;
 }

 NOTE the commented assert lines, uncommenting them causes decode to call 
 encode to call decode to call encode ...

 It must be my lack of imagination but how do I get round this?

 Or.. is this a bug?

 Should DBC blocks be processed for functions used within DBC blocks? or 
 not?

 Regan.
-- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jun 08 2004
parent reply Arcane Jill <Arcane_member pathlink.com> writes:
In article <opr9aq0w0o5a2sq9 digitalmars.com>, Regan Heath says...
No-one?

How do I solve this, do people think this is a bug in the design of DBC...

Basically you cannot have a pair of functions test each other, this is 
desirable for any encode/decode pair, eg.
Basically, you don't. The trick is to put an out condition on decode only. So:
       T encode(T x) { /*whatever*/ }
       T decode(T x)
       out(y)
       {
           assert(encode(y) == x);
       }
Well, that's what I did for some of the functions in Int anyway. Observe that if you call encode() only, nothing gets tested - BUT - if you call decode() only, BOTH encode and decode get tested. If there is anything wrong with EITHER of them, you will get the assert. (Unless the bugs cancel each other out, but then having two asserts wouldn't have helped anyway). Arcane Jill
Jun 08 2004
parent Regan Heath <regan netwin.co.nz> writes:
On Tue, 8 Jun 2004 22:54:20 +0000 (UTC), Arcane Jill 
<Arcane_member pathlink.com> wrote:
 In article <opr9aq0w0o5a2sq9 digitalmars.com>, Regan Heath says...
 No-one?

 How do I solve this, do people think this is a bug in the design of 
 DBC...

 Basically you cannot have a pair of functions test each other, this is
 desirable for any encode/decode pair, eg.
Basically, you don't. The trick is to put an out condition on decode only. So:
Ahh.. I don't really like it, but I can't think of a better soln. :(
       T encode(T x) { /*whatever*/ }
       T decode(T x)
       out(y)
       {
           assert(encode(y) == x);
       }
Well, that's what I did for some of the functions in Int anyway. Observe that if you call encode() only, nothing gets tested - BUT - if you call decode() only, BOTH encode and decode get tested. If there is anything wrong with EITHER of them, you will get the assert. (Unless the bugs cancel each other out, but then having two asserts wouldn't have helped anyway).
True... What about not processing dbc blocks if called from within a dbc block? It would stop the Stack Overflow, but, it would also cut down the number of times things are dbc tested. Regan
 Arcane Jill
-- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jun 08 2004