Thread overview
Screwed up decrement of bytes and shorts
Apr 18, 2005
Stewart Gordon
Apr 18, 2005
Thomas Kuehne
Apr 18, 2005
Tom S
Apr 19, 2005
Thomas Kuehne
Apr 19, 2005
Stewart Gordon
April 18, 2005
Using DMD 0.120, Windows 98SE.

---------
import std.stdio;

void main() {
	byte x = 9;
	writefln(x);
	writefln(--x);
}
---------
9
6618376
---------

The bug also happens with ubyte, short and ushort.  It disappears when:
- the writefln(x) statement is removed
- an intermediate variable of same-size or smaller type is used, like this

    writefln(x);
    byte y = --x;
    writefln(y);

but it still happens if the intermediate variable is a larger integer type.

Using --x as an array index screws up similarly, tending to cause an ArrayBoundsError:

---------
import std.stdio;

int[12] MONTH_OFFSET = [
    -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333
];

void main() {
    byte month = 9;

    writefln(month);
    int off = MONTH_OFFSET[--month];
    writefln(off);
}
----------

Presumably ++ has the same bug, but I didn't get round to testing it. Nor did I get round to testing postincrement/decrement....

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.
April 18, 2005
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Stewart Gordon schrieb am Mon, 18 Apr 2005 11:32:20 +0100:
> Using DMD 0.120, Windows 98SE.

I can't reproduce this with Linux and dmd 0.110 .. 0.121.

Does the sample below reproduce the error on your system?


void dummy(...){
}

int main(){
	byte x=9;
	dummy(x);
	dummy(--x);
	printf("%i\n", x);
	return 0;
}

Thomas


-----BEGIN PGP SIGNATURE-----

iD8DBQFCY7Gz3w+/yD4P9tIRAp+MAKDMVD28qXt/8g1Ex3YqYHMmkCgKfwCfdfjD
OomRyDods8qiQBhdYqppGz4=
=Rc1e
-----END PGP SIGNATURE-----
April 18, 2005
Stewart Gordon wrote:

> Using DMD 0.120, Windows 98SE.
> 
> ---------
> import std.stdio;
> 
> void main() {
>     byte x = 9;
>     writefln(x);
>     writefln(--x);
> }
> ---------
> 9
> 6618376
> ---------


Confirmed. I'm getting the same bug with DMD 0.121 on WinXP SP2
Yet the numbers are different
---------
9
1244936
---------

What's specific about the second number is that its hexadecimal representation == 12FF08h. The last byte == 8. With your numbers, it's 64FD08h, so again the last byte == 8. When using a short, I'm getting 120008, so again, the last word == 8. For some reason the compiler is confusing that bytes and shorts with ints.

The bug goes away when compiling with ' -o '.
This runs as expected:

---------
import std.stdio;

void main() {
    byte x = 9;
    writefln(x);
    --x;
    writefln(x);
}
---------


-- 
Tomasz Stachowiak  /+ a.k.a. h3r3tic +/
April 19, 2005
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Stewart Gordon schrieb am Mon, 18 Apr 2005 11:32:20 +0100:
> Using DMD 0.120, Windows 98SE.
>
> ---------
> import std.stdio;
>
> void main() {
> 	byte x = 9;
> 	writefln(x);
> 	writefln(--x);
> }
> ---------
> 9
> 6618376
> ---------
>
> The bug also happens with ubyte, short and ushort.  It disappears when:
> - the writefln(x) statement is removed
> - an intermediate variable of same-size or smaller type is used, like this
>
>      writefln(x);
>      byte y = --x;
>      writefln(y);
>
> but it still happens if the intermediate variable is a larger integer type.
>
> Using --x as an array index screws up similarly, tending to cause an ArrayBoundsError:
>
> ---------
> import std.stdio;
>
> int[12] MONTH_OFFSET = [
>      -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333
> ];
>
> void main() {
>      byte month = 9;
>
>      writefln(month);
>      int off = MONTH_OFFSET[--month];
>      writefln(off);
> }

Added to DStress as http://dstress.kuehne.cn/run/opPostDec_01.d http://dstress.kuehne.cn/run/opPostDec_02.d http://dstress.kuehne.cn/run/opPostDec_03.d http://dstress.kuehne.cn/run/opPostDec_04.d http://dstress.kuehne.cn/run/opPostDec_05.d http://dstress.kuehne.cn/run/opPostDec_06.d http://dstress.kuehne.cn/run/opPostDec_07.d http://dstress.kuehne.cn/run/opPostDec_08.d http://dstress.kuehne.cn/run/opPostDec_09.d http://dstress.kuehne.cn/run/opPostDec_10.d http://dstress.kuehne.cn/run/opPostDec_11.d http://dstress.kuehne.cn/run/opPostInc_01.d http://dstress.kuehne.cn/run/opPostInc_02.d http://dstress.kuehne.cn/run/opPostInc_03.d http://dstress.kuehne.cn/run/opPostInc_04.d http://dstress.kuehne.cn/run/opPostInc_05.d http://dstress.kuehne.cn/run/opPostInc_06.d http://dstress.kuehne.cn/run/opPostInc_07.d http://dstress.kuehne.cn/run/opPostInc_08.d http://dstress.kuehne.cn/run/opPostInc_09.d http://dstress.kuehne.cn/run/opPostInc_10.d http://dstress.kuehne.cn/run/opPostInc_11.d http://dstress.kuehne.cn/run/opPreDec_01.d http://dstress.kuehne.cn/run/opPreDec_02.d http://dstress.kuehne.cn/run/opPreDec_03.d http://dstress.kuehne.cn/run/opPreDec_04.d http://dstress.kuehne.cn/run/opPreDec_05.d http://dstress.kuehne.cn/run/opPreDec_06.d http://dstress.kuehne.cn/run/opPreDec_07.d http://dstress.kuehne.cn/run/opPreDec_08.d http://dstress.kuehne.cn/run/opPreDec_09.d http://dstress.kuehne.cn/run/opPreDec_10.d http://dstress.kuehne.cn/run/opPreDec_11.d http://dstress.kuehne.cn/run/opPreInc_01.d http://dstress.kuehne.cn/run/opPreInc_02.d http://dstress.kuehne.cn/run/opPreInc_03.d http://dstress.kuehne.cn/run/opPreInc_04.d http://dstress.kuehne.cn/run/opPreInc_05.d http://dstress.kuehne.cn/run/opPreInc_06.d http://dstress.kuehne.cn/run/opPreInc_07.d http://dstress.kuehne.cn/run/opPreInc_08.d http://dstress.kuehne.cn/run/opPreInc_09.d http://dstress.kuehne.cn/run/opPreInc_10.d http://dstress.kuehne.cn/run/opPreInc_11.d

Thomas


-----BEGIN PGP SIGNATURE-----

iD8DBQFCZITN3w+/yD4P9tIRAkaAAKC837Jp7swBMZn/T02/rQyDFEhNMwCfR0MG
H0EZjuNcd7DZ8LWHm0wuKZY=
=OxKb
-----END PGP SIGNATURE-----
April 19, 2005
Thomas Kuehne wrote:
<snip>
> Added to DStress as
> http://dstress.kuehne.cn/run/opPostDec_01.d
<snip>

These testcases aren't quite adequate - they test only the final value of the variable, not the value of the increment/decrement expressions.

But this reproduced the problem:

----------
void dummy(...) {}

void main() {
   byte x = 9;
   dummy(x);
   int y = --x;
   assert (y == 8);
   assert (x == 8);
}
----------

I also found the exact same problem with +=.  Probably -= as well, but strangely *= didn't show it.  We should have some testcases for various op= as well as both prefix and postfix ++ and --.

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.