www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Bug in the spec or implementation?

reply simendsjo <simen.endsjo pandavre.com> writes:
This is only tested on dmd 2.047 on win7.

According to the spec at http://digitalmars.com/d/2.0/arrays.html:
"Concatenation always creates a copy of its operands, even if one of the 
operands is a 0 length array"

But this doesn't seem like the case:

	auto a = [0];
	auto oldPtr = a.ptr;
	assert(a.length == 1);
	assert(a.capacity == 3);
	a ~= 1;
	assert(a.ptr != oldPtr); // Fails - Still the same array
Aug 05 2010
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 05 Aug 2010 14:45:18 -0400, simendsjo <simen.endsjo pandavre.com>  
wrote:

 This is only tested on dmd 2.047 on win7.

 According to the spec at http://digitalmars.com/d/2.0/arrays.html:
 "Concatenation always creates a copy of its operands, even if one of the  
 operands is a 0 length array"

 But this doesn't seem like the case:

 	auto a = [0];
 	auto oldPtr = a.ptr;
 	assert(a.length == 1);
 	assert(a.capacity == 3);
 	a ~= 1;
 	assert(a.ptr != oldPtr); // Fails - Still the same array
Concatenation is this: a ~ 1 appending is this: a ~= 1 Two separate operations, two separate semantics. It might not be easy to determine that from the spec, but I believe the spec is clear. -Steve
Aug 05 2010
parent reply simendsjo <simen.endsjo pandavre.com> writes:
On 05.08.2010 20:53, Steven Schveighoffer wrote:
 On Thu, 05 Aug 2010 14:45:18 -0400, simendsjo
 <simen.endsjo pandavre.com> wrote:

 This is only tested on dmd 2.047 on win7.

 According to the spec at http://digitalmars.com/d/2.0/arrays.html:
 "Concatenation always creates a copy of its operands, even if one of
 the operands is a 0 length array"

 But this doesn't seem like the case:

 auto a = [0];
 auto oldPtr = a.ptr;
 assert(a.length == 1);
 assert(a.capacity == 3);
 a ~= 1;
 assert(a.ptr != oldPtr); // Fails - Still the same array
Concatenation is this: a ~ 1 appending is this: a ~= 1 Two separate operations, two separate semantics. It might not be easy to determine that from the spec, but I believe the spec is clear. -Steve
Hmm... Doing "a = a ~ 1", and it works like specified. I always assumed that composite operators would mean the same.. That "a += 1" is the same as "a = a + 1" etc. I cannot find this behavior explained in the spec though.. From the Expression spec, I found that "a op= b" is the same as "a = a op b" - see "Assignment Operator Expressions". No mention of a CatAssignExpression behaving differently. Array doesn't mention anything either.
Aug 05 2010
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 05 Aug 2010 15:13:26 -0400, simendsjo <simen.endsjo pandavre.com>  
wrote:

 On 05.08.2010 20:53, Steven Schveighoffer wrote:
 On Thu, 05 Aug 2010 14:45:18 -0400, simendsjo
 <simen.endsjo pandavre.com> wrote:

 This is only tested on dmd 2.047 on win7.

 According to the spec at http://digitalmars.com/d/2.0/arrays.html:
 "Concatenation always creates a copy of its operands, even if one of
 the operands is a 0 length array"

 But this doesn't seem like the case:

 auto a = [0];
 auto oldPtr = a.ptr;
 assert(a.length == 1);
 assert(a.capacity == 3);
 a ~= 1;
 assert(a.ptr != oldPtr); // Fails - Still the same array
Concatenation is this: a ~ 1 appending is this: a ~= 1 Two separate operations, two separate semantics. It might not be easy to determine that from the spec, but I believe the spec is clear. -Steve
Hmm... Doing "a = a ~ 1", and it works like specified. I always assumed that composite operators would mean the same.. That "a += 1" is the same as "a = a + 1" etc. I cannot find this behavior explained in the spec though.. From the Expression spec, I found that "a op= b" is the same as "a = a op b" - see "Assignment Operator Expressions". No mention of a CatAssignExpression behaving differently. Array doesn't mention anything either.
I found this line in the spec: "These issues also apply to concatenating arrays with the ~ and ~= operators." Where "These issues" refer to reallocating in place (look at the section for setting the length of an array). I think this line is in error, as it directly conflicts with the statement: "Concatenation always creates a copy of its operands, even if one of the operands is a 0 length array" I think the line should read: "These issues also apply to appending arrays with the ~= operator. Note that the concatenation operator ~ is not affected since it always reallocates." I can assure you that the runtime does always make a copy on concatenation, and always tries to append in place if possible on an expanding length or an append. The spec needs some work, but the runtime is correct. I will file a bug against the spec for you. -Steve
Aug 05 2010
parent reply simendsjo <simen.endsjo pandavre.com> writes:
On 05.08.2010 21:41, Steven Schveighoffer wrote:
 On Thu, 05 Aug 2010 15:13:26 -0400, simendsjo
 <simen.endsjo pandavre.com> wrote:

 I found this line in the spec:

 "These issues also apply to concatenating arrays with the ~ and ~=
 operators."

 Where "These issues" refer to reallocating in place (look at the section
 for setting the length of an array).

 I think this line is in error, as it directly conflicts with the statement:

 "Concatenation always creates a copy of its operands, even if one of the
 operands is a 0 length array"

 I think the line should read:

 "These issues also apply to appending arrays with the ~= operator. Note
 that the concatenation operator ~ is not affected since it always
 reallocates."

 I can assure you that the runtime does always make a copy on
 concatenation, and always tries to append in place if possible on an
 expanding length or an append.

 The spec needs some work, but the runtime is correct.

 I will file a bug against the spec for you.

 -Steve
Thanks! Seems there are plenty of errors in the spec though... It will be very difficult to learn the language if the spec and implementation is different. Spec or compiler bug? char[] a = new char[20]; char[] b = a[0..10]; assert(a.ptr == b.ptr); // hmm.. does slice has a offset property or something? // In the spec on arrays#Setting Dynamic Array Length, // this is the example, but it doesn't work as in the spec... char[] c = a[10..20]; // The spec says expanding b.length should expand // in place as a has enough memory and thus overlapping a, but... assert(b.capacity == 0); // capacity is 0, so... b.length = 15; assert(b.capacity == 15); // .. setting length removed it from a.. assert(a.ptr == b.ptr); // fails... b[11] = 'x'; // Says a[11] and c[1] should also change.. assert(a[11] == 'x'); // fails assert(c[1] == 'x'); // fails
Aug 05 2010
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 05 Aug 2010 16:00:35 -0400, simendsjo <simen.endsjo pandavre.com>  
wrote:

 On 05.08.2010 21:41, Steven Schveighoffer wrote:
 On Thu, 05 Aug 2010 15:13:26 -0400, simendsjo
 <simen.endsjo pandavre.com> wrote:

 I found this line in the spec:

 "These issues also apply to concatenating arrays with the ~ and ~=
 operators."

 Where "These issues" refer to reallocating in place (look at the section
 for setting the length of an array).

 I think this line is in error, as it directly conflicts with the  
 statement:

 "Concatenation always creates a copy of its operands, even if one of the
 operands is a 0 length array"

 I think the line should read:

 "These issues also apply to appending arrays with the ~= operator. Note
 that the concatenation operator ~ is not affected since it always
 reallocates."

 I can assure you that the runtime does always make a copy on
 concatenation, and always tries to append in place if possible on an
 expanding length or an append.

 The spec needs some work, but the runtime is correct.

 I will file a bug against the spec for you.

 -Steve
Thanks! Seems there are plenty of errors in the spec though... It will be very difficult to learn the language if the spec and implementation is different. Spec or compiler bug? char[] a = new char[20]; char[] b = a[0..10]; assert(a.ptr == b.ptr); // hmm.. does slice has a offset property or something? // In the spec on arrays#Setting Dynamic Array Length, // this is the example, but it doesn't work as in the spec... char[] c = a[10..20]; // The spec says expanding b.length should expand // in place as a has enough memory and thus overlapping a, but... assert(b.capacity == 0); // capacity is 0, so... b.length = 15; assert(b.capacity == 15); // .. setting length removed it from a.. assert(a.ptr == b.ptr); // fails... b[11] = 'x'; // Says a[11] and c[1] should also change.. assert(a[11] == 'x'); // fails assert(c[1] == 'x'); // fails
Yep, I noticed that too when going to file the bug :) see here: http://d.puremagic.com/issues/show_bug.cgi?id=4590 I should take responsibility for not fixing this sooner since the runtime used to work this way, but does not since a patch I added in 2.041 or 2.042. Sorry. -Steve
Aug 05 2010
parent reply simendsjo <simen.endsjo pandavre.com> writes:
On 05.08.2010 22:24, Steven Schveighoffer wrote:
 On Thu, 05 Aug 2010 16:00:35 -0400, simendsjo
 <simen.endsjo pandavre.com> wrote:

 On 05.08.2010 21:41, Steven Schveighoffer wrote:
(...)
 Seems there are plenty of errors in the spec though...
 It will be very difficult to learn the language if the spec and
 implementation is different. Spec or compiler bug?


 char[] a = new char[20];
 char[] b = a[0..10];
 assert(a.ptr == b.ptr); // hmm.. does slice has a offset property or
 something?

 // In the spec on arrays#Setting Dynamic Array Length,
 // this is the example, but it doesn't work as in the spec...

 char[] c = a[10..20];
 // The spec says expanding b.length should expand
 // in place as a has enough memory and thus overlapping a, but...
 assert(b.capacity == 0); // capacity is 0, so...
 b.length = 15;
 assert(b.capacity == 15); // .. setting length removed it from a..
 assert(a.ptr == b.ptr); // fails...
 b[11] = 'x'; // Says a[11] and c[1] should also change..
 assert(a[11] == 'x'); // fails
 assert(c[1] == 'x'); // fails
Yep, I noticed that too when going to file the bug :) see here: http://d.puremagic.com/issues/show_bug.cgi?id=4590 I should take responsibility for not fixing this sooner since the runtime used to work this way, but does not since a patch I added in 2.041 or 2.042. Sorry. -Steve
Thanks again! Hope spec bugs have high priorities as it's difficult to learn the language otherwise. Are the compiler pretty stable, so I can assume most bugs are in the spec, or is it the other way around?
Aug 05 2010
next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
I think I might have made a report about this already, under "setting
dynamic array length" here
 http://d.puremagic.com/issues/show_bug.cgi?id=4551 .

I didn't file it as a DMD bug, I've filed a bunch of stuff for the spec (as
you can see in the other "D2 Language Docs" bug reports of mine), so I'm
hoping sooner or later someone could take a look at those (I've also
provided some fixes in there).
Aug 05 2010
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 05 Aug 2010 16:39:48 -0400, Andrej Mitrovic  
<andrej.mitrovich gmail.com> wrote:

 I think I might have made a report about this already, under "setting
 dynamic array length" here
  http://d.puremagic.com/issues/show_bug.cgi?id=4551 .

 I didn't file it as a DMD bug, I've filed a bunch of stuff for the spec  
 (as
 you can see in the other "D2 Language Docs" bug reports of mine), so I'm
 hoping sooner or later someone could take a look at those (I've also
 provided some fixes in there).
Yes, it is the same problem, but I'd like to keep both open because mine contains a fix for the spec, whereas yours just points out the problem (understandably). And it's not a dmd bug anyways, it's a spec bug. -Steve
Aug 05 2010
prev sibling parent Don <nospam nospam.com> writes:
simendsjo wrote:
 On 05.08.2010 22:24, Steven Schveighoffer wrote:
 On Thu, 05 Aug 2010 16:00:35 -0400, simendsjo
 <simen.endsjo pandavre.com> wrote:

 On 05.08.2010 21:41, Steven Schveighoffer wrote:
(...)
 Seems there are plenty of errors in the spec though...
 It will be very difficult to learn the language if the spec and
 implementation is different. Spec or compiler bug?


 char[] a = new char[20];
 char[] b = a[0..10];
 assert(a.ptr == b.ptr); // hmm.. does slice has a offset property or
 something?

 // In the spec on arrays#Setting Dynamic Array Length,
 // this is the example, but it doesn't work as in the spec...

 char[] c = a[10..20];
 // The spec says expanding b.length should expand
 // in place as a has enough memory and thus overlapping a, but...
 assert(b.capacity == 0); // capacity is 0, so...
 b.length = 15;
 assert(b.capacity == 15); // .. setting length removed it from a..
 assert(a.ptr == b.ptr); // fails...
 b[11] = 'x'; // Says a[11] and c[1] should also change..
 assert(a[11] == 'x'); // fails
 assert(c[1] == 'x'); // fails
Yep, I noticed that too when going to file the bug :) see here: http://d.puremagic.com/issues/show_bug.cgi?id=4590 I should take responsibility for not fixing this sooner since the runtime used to work this way, but does not since a patch I added in 2.041 or 2.042. Sorry. -Steve
Thanks again! Hope spec bugs have high priorities as it's difficult to learn the language otherwise. Are the compiler pretty stable, so I can assume most bugs are in the spec, or is it the other way around?
Rule of thumb: If the code compiles, but behaves differently to what the spec says, you can be pretty sure it's a spec bug. If the spec says it should work, but the compiler rejects it, it's most likely a compiler bug.
Aug 06 2010