www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - D bug or not?

reply Shawn Liu <Shawn_member pathlink.com> writes:
import std.stdio;
int[4]  sInt = [1,2,3,4];

void main() {
int[] array2 = new int[sInt.length];

int index = 0;
for(int i=0; i<sInt.length; i++)	{
array2[index] = sInt[index++];
}
for(int i=0; i<array2.length;i++)	{
writefln("array2[",i,"] = ", array2[i]);
}	
}

array2[0] = 0
array2[1] = 1
array2[2] = 2
array2[3] = 3

The problem may be at "array2[index] = sInt[index++]". My thought is,
D do a Right-to-Left calculation, index becomes "1" before array2[0] be assigned
a value. So array2[0] is never assigned a value. But how can D assign
array2[4]??
And this is far different from Java or C/C++ does.
Aug 18 2005
next sibling parent reply Manfred Nowak <svv1999 hotmail.com> writes:
Shawn Liu <Shawn_member pathlink.com> wrote:

 But how can D assign array2[4]??

The same way that C does assign to cells out of bounds. And because you are using an illegal instruction you are tricking out the ArrayBoundsCheck of dmd. -manfred
Aug 18 2005
parent reply Shawn Liu <Shawn_member pathlink.com> writes:
In article <de1j3q$1rpl$1 digitaldaemon.com>, Manfred Nowak says...
Shawn Liu <Shawn_member pathlink.com> wrote:

 But how can D assign array2[4]??

The same way that C does assign to cells out of bounds. And because you are using an illegal instruction you are tricking out the ArrayBoundsCheck of dmd. -manfred

1) The posted D code works with no compile or runtime error at all. No ArrayBoundsCheck exception. 2) I tested this code for C, C++ and Java. And all give the right answer: 1,2,3,4 not 0,1,2,3
Aug 18 2005
parent reply Manfred Nowak <svv1999 hotmail.com> writes:
Shawn Liu <Shawn_member pathlink.com> wrote:

[...]
 1) The posted D code works with no compile or runtime error at
 all. No ArrayBoundsCheck exception. 

For illegal expressions there are no guarantees.
 2) I tested this code for C, C++ and Java. And all give the
 right answer: 1,2,3,4 not 0,1,2,3

The expression in question is illegal, therefore there is no right answer. At least in C the order of evaluation for binary operators is as undefined as in D. If you got a desired result in your test, you were lucky. Please dont blame the bugs in the sources you want to port to D. -manfred
Aug 18 2005
parent "Shawn Liu" <shawn666.liu gmail.com> writes:
"Manfred Nowak" <svv1999 hotmail.com> 
wrote:de27b3$2oqf$1 digitaldaemon.com...
 The expression in question is illegal, therefore there is no right
 answer. At least in C the order of evaluation for binary operators is
 as undefined as in D. If you got a desired result in your test, you
 were lucky.

 Please dont blame the bugs in the sources you want to port to D.

 -manfred

Yes. According to http://digitalmars.com/d/expression.html, We should avoid these kind of codes. But a compile error or warning will be helpful.
Aug 18 2005
prev sibling next sibling parent reply Chris Sauls <ibisbasenji gmail.com> writes:
Shawn Liu wrote:
 import std.stdio;
 int[4]  sInt = [1,2,3,4];
 
 void main() {
 int[] array2 = new int[sInt.length];
 
 int index = 0;
 for(int i=0; i<sInt.length; i++)	{
 array2[index] = sInt[index++];
 }
 for(int i=0; i<array2.length;i++)	{
 writefln("array2[",i,"] = ", array2[i]);
 }	
 }
 
 array2[0] = 0
 array2[1] = 1
 array2[2] = 2
 array2[3] = 3
 
 The problem may be at "array2[index] = sInt[index++]". My thought is,
 D do a Right-to-Left calculation, index becomes "1" before array2[0] be
assigned
 a value. So array2[0] is never assigned a value. But how can D assign
 array2[4]??
 And this is far different from Java or C/C++ does.

Change the first loop to this, and it works: # for(int i=0; i<sInt.length; i++) { # array2[index] = sInt[index]; # index++; # } I'm not sure what you were really trying to do, but this would have been simpler: # import std.stdio; # # int[4] sInt = [1, 2, 3, 4] ; # # void main() { # int[] array2 = new int[sInt.length] ; # # foreach (size_t idx, inout int elem; array2) # elem = sInt[idx]; # # foreach (size_t idx, int elem; array2) # writefln("array2[%d] = %d", idx, elem); # } And this would be simplest: # import std.stdio; # # int[4] sInt = [1, 2, 3, 4] ; # # void main() { # int[] array2 = sInt[]; # # foreach (size_t idx, int elem; array2) # writefln("array2[%d] = %d", idx, elem); # } -- Chris Sauls
Aug 18 2005
parent reply Shawn Liu <Shawn_member pathlink.com> writes:
In article <de1mtr$1vun$1 digitaldaemon.com>, Chris Sauls says...
Change the first loop to this, and it works:
#  for(int i=0; i<sInt.length; i++) {
#    array2[index] = sInt[index];
#    index++;
#  }

Currently, I changed the code like this.
I'm not sure what you were really trying to do, but this would have been 

I am porting SWT (a Java project) to D. This code seems no error at all. It works fine with Java, but generates strange problem in D. And it is very hard to detect. It takes me several hours to debug step by step to catch this.
Aug 18 2005
parent reply Chris Sauls <ibisbasenji gmail.com> writes:
Shawn Liu wrote:
 In article <de1mtr$1vun$1 digitaldaemon.com>, Chris Sauls says...
 
Change the first loop to this, and it works:
#  for(int i=0; i<sInt.length; i++) {
#    array2[index] = sInt[index];
#    index++;
#  }

Currently, I changed the code like this.
I'm not sure what you were really trying to do, but this would have been 

I am porting SWT (a Java project) to D. This code seems no error at all. It works fine with Java, but generates strange problem in D. And it is very hard to detect. It takes me several hours to debug step by step to catch this.

Ahh, I see. I knew you were working (hard) on DWT, but didn't know this was related to that at all. It is an odd error and I'm not sure exactly how the increment operator is causing it, but it does seem to be the culprit. Order of evaluation is the most likely case, but even then... -- Chris Sauls
Aug 18 2005
parent reply xs0 <xs0 xs0.com> writes:
Chris Sauls wrote:
 Shawn Liu wrote:
 
 In article <de1mtr$1vun$1 digitaldaemon.com>, Chris Sauls says...

 Change the first loop to this, and it works:
 #  for(int i=0; i<sInt.length; i++) {
 #    array2[index] = sInt[index];
 #    index++;
 #  }

Currently, I changed the code like this.
 I'm not sure what you were really trying to do, but this would have been 

I am porting SWT (a Java project) to D. This code seems no error at all. It works fine with Java, but generates strange problem in D. And it is very hard to detect. It takes me several hours to debug step by step to catch this.

Ahh, I see. I knew you were working (hard) on DWT, but didn't know this was related to that at all. It is an odd error and I'm not sure exactly how the increment operator is causing it, but it does seem to be the culprit. Order of evaluation is the most likely case, but even then...

Well, array2[index] = sInt[index++]; decomposes into something like A) int *dest=array2.ptr+index; B) int src=sInt[index]; C) index=index+1; D) *dest=src; The only specified ordering constraints would then be A before D B before C B before D But this can be done in a number of ways: ABCD ABDC BACD BADC BCAD And even though only the last one has C before A (which is what causes the error), it would seem that it is exactly the case that is evaluated :) But still, it's not a bug, because the expressions spec explicitly states that the order of evaluation is unspecified. Although it would definitely be nice if the compiler would produce an error - the check could really be quite simple, even.. if a variable that is incremented or decremented is used again in the same expression, it's an error.. Not 100% proof, but should catch most errors.. BTW, why don't you just do array2[]=sInt; // copies the entire array or even int[] array2=sInt.dup; // allocates it, too ? Disclaimer: I may be wrong about everything in this post :) xs0
Aug 18 2005
parent "Shawn Liu" <shawn666.liu gmail.com> writes:
"xs0" <xs0 xs0.com> wrote:de1rc9$27sp$1 digitaldaemon.com...
 Chris Sauls wrote:> Well, array2[index] = sInt[index++]; decomposes into 
 something like

 A) int *dest=array2.ptr+index;
 B) int src=sInt[index];
 C) index=index+1;
 D) *dest=src;

 The only specified ordering constraints would then be

 A before D
 B before C
 B before D

 But this can be done in a number of ways:

 ABCD
 ABDC
 BACD
 BADC
 BCAD

 And even though only the last one has C before A (which is what causes the 
 error), it would seem that it is exactly the case that is evaluated :) But 
 still, it's not a bug, because the expressions spec explicitly states that 
 the order of evaluation is unspecified. Although it would definitely be 
 nice if the compiler would produce an error - the check could really be 
 quite simple, even.. if a variable that is incremented or decremented is 
 used again in the same expression, it's an error.. Not 100% proof, but 
 should catch most errors..

 BTW, why don't you just do

 array2[]=sInt; // copies the entire array

 or even

 int[] array2=sInt.dup; // allocates it, too

 ?


 Disclaimer: I may be wrong about everything in this post :)


 xs0

The original Java code is from org.eclipse.swt.custom.CTabFolder.antialias(...) : # boolean left; # int[] outer = new int[shape.length]; # for (int i = 0; i < shape.length/2; i++) { # ...... # outer[index] = shape[index++] + (left ? -1 : +1); # outer[index] = shape[index++]; # } Giving a minimal cost to port something is to keep the original code as much as possible. This will take the advantage of bug tracking and upgrading. So we don't wanna convert everything in D way. Actually, it will be painful within a big project. So this java code is kept and compiled. Since it passed the compiling, we may think it has the same behavior as Java or C++ does. . I have tested the same code in C++ and Java. Both assign the target array using the index without "1" plused, and get the result "1,2,3,4" not "0,1,2,3". I think there may be other project port from Java or C++. So make D to compliant with Java/C++ or give a error at compile time will be appreciated.
Aug 18 2005
prev sibling parent Dave <Dave_member pathlink.com> writes:
Look at "Evaluation Order" in:

http://digitalmars.com/d/expression.html

I think the doc. should add an array index/postfix op. example as well.

- Dave

In article <de1e3b$1lra$1 digitaldaemon.com>, Shawn Liu says...
import std.stdio;
int[4]  sInt = [1,2,3,4];

void main() {
int[] array2 = new int[sInt.length];

int index = 0;
for(int i=0; i<sInt.length; i++)	{
array2[index] = sInt[index++];
}
for(int i=0; i<array2.length;i++)	{
writefln("array2[",i,"] = ", array2[i]);
}	
}

array2[0] = 0
array2[1] = 1
array2[2] = 2
array2[3] = 3

The problem may be at "array2[index] = sInt[index++]". My thought is,
D do a Right-to-Left calculation, index becomes "1" before array2[0] be assigned
a value. So array2[0] is never assigned a value. But how can D assign
array2[4]??
And this is far different from Java or C/C++ does.

Aug 18 2005