www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - arr.length as lvalue

reply Lars Ivar Igesund <larsivar igesund.net> writes:
Why do

arr.length = arr.length + 1;

work when

arr.length += 1;

and

arr.length++;

don't ("arr.length is not an lvalue")?
AFAIK, arr.length is an lvalue in the first statement, too.

Lars Ivar Igesund
Sep 20 2004
next sibling parent reply Burton Radons <burton-radons shaw.ca> writes:
Lars Ivar Igesund wrote:
 Why do
 
 arr.length = arr.length + 1;
 
 work when
 
 arr.length += 1;
 
 and
 
 arr.length++;
 
 don't ("arr.length is not an lvalue")?
 AFAIK, arr.length is an lvalue in the first statement, too.

It was introduced to prevent: arr [arr.length ++] = foo; Which has an undefined result.
Sep 20 2004
next sibling parent reply Regan Heath <regan netwin.co.nz> writes:
On Mon, 20 Sep 2004 13:58:40 -0700, Burton Radons <burton-radons shaw.ca> 
wrote:
 Lars Ivar Igesund wrote:
 Why do

 arr.length = arr.length + 1;

 work when

 arr.length += 1;

 and

 arr.length++;

 don't ("arr.length is not an lvalue")?
 AFAIK, arr.length is an lvalue in the first statement, too.

It was introduced to prevent: arr [arr.length ++] = foo; Which has an undefined result.

I don't think that has an undefined result, AFAIKS: - the value of arr.length is taken (L) - arr.length is incremented. - foo is assigned to arr[L]. eg. L = arr.length; arr.length++; arr[L] = foo; If however the expression 'foo' modified arr.length you'd have a different story, so I assume that is what you meant? In which case can't we rely on precedence rules applying i.e. the RHS is evaluated then the LHS or something. I say this because I think arr.length++ is intuitive and therefore desirable. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Sep 20 2004
next sibling parent reply Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
Regan Heath wrote:
 It was introduced to prevent:

     arr [arr.length ++] = foo;

 Which has an undefined result.

I don't think that has an undefined result, AFAIKS: - the value of arr.length is taken (L) - arr.length is incremented. - foo is assigned to arr[L]. eg. L = arr.length; arr.length++; arr[L] = foo;

Since it's post increment, isn't the sequence actually: arr[arr.length] = foo; arr.length = arr.length + 1; which is obviously broken because you're exceeding the bounds of the array? Anyhow, what Walter has said is that he doesn't want to have arr.length++; because it makes it look like setting .length is as simple as addition, when actually it's a call to a fairly complex function. Please, let's not argue this (again). It's been argued at length - several times. Check the old posts, in both this newsgroup and the older one.
Sep 20 2004
next sibling parent reply Regan Heath <regan netwin.co.nz> writes:
On Mon, 20 Sep 2004 14:24:10 -0700, Russ Lewis 
<spamhole-2001-07-16 deming-os.org> wrote:
 Regan Heath wrote:
 It was introduced to prevent:

     arr [arr.length ++] = foo;

 Which has an undefined result.

I don't think that has an undefined result, AFAIKS: - the value of arr.length is taken (L) - arr.length is incremented. - foo is assigned to arr[L]. eg. L = arr.length; arr.length++; arr[L] = foo;

Since it's post increment, isn't the sequence actually: arr[arr.length] = foo; arr.length = arr.length + 1; which is obviously broken because you're exceeding the bounds of the array?

Oops, yes, you're right. In that case this restriction does stop this particular bug. Why is: arr.length += 100; restricted? it's probably the more useful of the two.
 Anyhow, what Walter has said is that he doesn't want to have
 	arr.length++;
 because it makes it look like setting .length is as simple as addition, 
 when actually it's a call to a fairly complex function.

Sure, but I don't think forcing people to use arr.length = arr.length + 1 causes anyone to realise that. More likely they just think WTF?! why can't I use arr.length++; I know I did.
 Please, let's not argue this (again).  It's been argued at length - 
 several times.

What that pun/joke intentional?
 Check the old posts, in both this newsgroup and the older one.

Ok, but can you answer my little question above and same me/everyone who does not know already the trouble of searching. Thanks in advance. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Sep 20 2004
next sibling parent Sha Chancellor <schancel pacific.net> writes:
In article <opsenbajbk5a2sq9 digitalmars.com>,
 Regan Heath <regan netwin.co.nz> wrote:

 On Mon, 20 Sep 2004 14:24:10 -0700, Russ Lewis 
 <spamhole-2001-07-16 deming-os.org> wrote:
 Regan Heath wrote:
 It was introduced to prevent:

     arr [arr.length ++] = foo;

 Which has an undefined result.

I don't think that has an undefined result, AFAIKS: - the value of arr.length is taken (L) - arr.length is incremented. - foo is assigned to arr[L]. eg. L = arr.length; arr.length++; arr[L] = foo;

Since it's post increment, isn't the sequence actually: arr[arr.length] = foo; arr.length = arr.length + 1; which is obviously broken because you're exceeding the bounds of the array?

Oops, yes, you're right. In that case this restriction does stop this particular bug. Why is: arr.length += 100; restricted? it's probably the more useful of the two.
 Anyhow, what Walter has said is that he doesn't want to have
 	arr.length++;
 because it makes it look like setting .length is as simple as addition, 
 when actually it's a call to a fairly complex function.

Sure, but I don't think forcing people to use arr.length = arr.length + 1 causes anyone to realise that. More likely they just think WTF?! why can't I use arr.length++; I know I did.
 Please, let's not argue this (again).  It's been argued at length - 
 several times.

What that pun/joke intentional?
 Check the old posts, in both this newsgroup and the older one.

Ok, but can you answer my little question above and same me/everyone who does not know already the trouble of searching. Thanks in advance. Regan

I think it's rather silly that a so called attribute has a special behavior here. It should be obvious that it's a function and not an lvalue if it is indeed a function. arr.setLength() or something would be much clearer. Because arr.length = arr.length + 1 makes it look like it's simple addition.....
Sep 20 2004
prev sibling parent reply Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
Regan Heath wrote:
 Anyhow, what Walter has said is that he doesn't want to have
     arr.length++;
 because it makes it look like setting .length is as simple as 
 addition, when actually it's a call to a fairly complex function.

Sure, but I don't think forcing people to use arr.length = arr.length + 1 causes anyone to realise that. More likely they just think WTF?! why can't I use arr.length++; I know I did.

 Please, let's not argue this (again).  It's been argued at length - 
 several times.

What that pun/joke intentional?

No, but I wish it had been! :)
 Check the old posts, in both this newsgroup and the older one.

Ok, but can you answer my little question above and same me/everyone who does not know already the trouble of searching.

Well, you're not the first to state this viewpoint. I, for one, agree with you. But only Big W can make the final language decisions. One thing in favor of his position, though, is that we could add support for the syntax later. If Walter allowed it now and we decided later that it was a bad idea, it would be almost impossible to remove from the language.
Sep 21 2004
parent reply Id <Id_member pathlink.com> writes:
In article <cipnh7$1g5n$1 digitaldaemon.com>, Russ Lewis says...
Regan Heath wrote:
 Anyhow, what Walter has said is that he doesn't want to have
     arr.length++;
 because it makes it look like setting .length is as simple as 
 addition, when actually it's a call to a fairly complex function.



Currently, dynamic arrays are composed of a: "length" and a "pointer to the array data". I've thought, what if we used this implementation?: "reserved length" -> "array length" -> "pointer to the array data" NOTE: ("reserved" is recommended to be a power of 2, and always >= array length) This implementation would increase the overhead of the array definition and probably break backwards compatibility, yet in most cases this would make concatenation a child's play in most cases, as you could do like this example: int[] a=new int[14]; //reserved=32(amount decided by the compiler), length=14, pointer=(somewhere) int b=a[15]; //Error, Out Of Bounds array.length=19; //Allocate memory? naaah! two CPU instructions and done! :) //reserved=32, length 19, pointer=(somewhere) array.length++; //(length+1)< reserved, so we got another cheap resize ;) //reserved=32, length 20, pointer=(somewhere) array.length=80; // (80 > reserved) Memory allocation is needed...the typical slow resize :( . // reserved=128, length 80, pointer=(whatever) array.reserved=5; //lol, nice hack attempt, but no. You can't access this. What do you say?
Sep 21 2004
parent Arcane Jill <Arcane_member pathlink.com> writes:
In article <ciq8jb$2nd8$1 digitaldaemon.com>, Id says...

Currently, dynamic arrays are composed of a:
"length" and a "pointer to the array data".

I've thought, what if we used this implementation?:

"reserved length" -> "array length" -> "pointer to the array data"
NOTE: ("reserved" is recommended to be a power of 2, and always >= array
length)

So what structure would a[1..4] return?
This implementation would increase the overhead of the array definition and
probably break backwards compatibility, yet in most cases this would make
concatenation a child's play in most cases, as you could do like this example:

int[] a=new int[14]; 
//reserved=32(amount decided by the compiler), length=14, pointer=(somewhere)

int b=a[15]; //Error, Out Of Bounds

array.length=19; //Allocate memory? naaah! two CPU instructions and done! :)
//reserved=32, length 19, pointer=(somewhere)

Which two, exactly?
array.length++; //(length+1)< reserved, so we got another cheap resize ;)
//reserved=32, length 20, pointer=(somewhere)

array.length=80; 
// (80 > reserved) Memory allocation is needed...the typical slow resize :( .
// reserved=128, length 80, pointer=(whatever)

array.reserved=5; //lol, nice hack attempt, but no. You can't access this.

Yes you can. A union does the trick nicely.
What do you say?

Did you forget about: # int[] a = new int[5]; # int[] b = a; # a.length = 6; # a[5] = 100; # b.length = 6; // What is b[5] now? Come to that, what is a[5]? I think it would break way too much. Jill
Sep 22 2004
prev sibling parent Sean Kelly <sean f4.ca> writes:
In article <cinhpr$574$1 digitaldaemon.com>, Russ Lewis says...
Regan Heath wrote:
 It was introduced to prevent:

     arr [arr.length ++] = foo;

 Which has an undefined result.

I don't think that has an undefined result, AFAIKS: - the value of arr.length is taken (L) - arr.length is incremented. - foo is assigned to arr[L]. eg. L = arr.length; arr.length++; arr[L] = foo;

Since it's post increment, isn't the sequence actually: arr[arr.length] = foo; arr.length = arr.length + 1; which is obviously broken because you're exceeding the bounds of the array?

I think the correct expression would be this: arr[++arr.length - 1] = foo; Which just reeks of undefined behavior. Sean
Sep 20 2004
prev sibling parent Burton Radons <burton-radons shaw.ca> writes:
Regan Heath wrote:

 I don't think that has an undefined result, AFAIKS:
 
 - the value of arr.length is taken (L)
 - arr.length is incremented.
 - foo is assigned to arr[L].

Nope; the comp.lang.c FAQ has a whole section essentially devoted to the subject (http://www.eskimo.com/~scs/C-faq/s3.html).
 If however the expression 'foo' modified arr.length you'd have a 
 different story, so I assume that is what you meant?

 In which case can't we rely on precedence rules applying i.e. the RHS is 
 evaluated then the LHS or something.

Neither lvalue/rvalue nor precedence have any effect on order of evaluation; only the sequence point.
 I say this because I think arr.length++ is intuitive and therefore 
 desirable.

I agree that it's a silly error, since it's not erroneous in most cases. Making the compiler identify the special case the error was built for or introducing logic to discover undefined expressions (like GCC has) would be better. That'll have to wait until after the bug fixes and the standard, though.
Sep 20 2004
prev sibling parent reply Sjoerd van Leent <svanleent wanadoo.nl> writes:
Burton Radons wrote:
 Lars Ivar Igesund wrote:
 
 Why do

 arr.length = arr.length + 1;

 work when

 arr.length += 1;

 and

 arr.length++;

 don't ("arr.length is not an lvalue")?
 AFAIK, arr.length is an lvalue in the first statement, too.

It was introduced to prevent: arr [arr.length ++] = foo; Which has an undefined result.

It seems also that arr.length++ is rather pointless, because when adding a new item to an array, it can be done with the append operator: int main (char[][] args) { byte[] ba; for(byte b = 0; b < 10; b++) { ba ~= b; } // prints bytes: 0 1 2 3 4 5 6 7 8 9 printf("bytes: "); foreach(byte b; ba) { printf("%d ", b); } printf(\n); return 1; } Regards, Sjoerd
Sep 20 2004
parent Lars Ivar Igesund <larsivar igesund.net> writes:
Sjoerd van Leent wrote:
 Burton Radons wrote:
 
 Lars Ivar Igesund wrote:

 Why do

 arr.length = arr.length + 1;

 work when

 arr.length += 1;

 and

 arr.length++;

 don't ("arr.length is not an lvalue")?
 AFAIK, arr.length is an lvalue in the first statement, too.

It was introduced to prevent: arr [arr.length ++] = foo; Which has an undefined result.

It seems also that arr.length++ is rather pointless, because when adding a new item to an array, it can be done with the append operator: int main (char[][] args) { byte[] ba; for(byte b = 0; b < 10; b++) { ba ~= b; } // prints bytes: 0 1 2 3 4 5 6 7 8 9 printf("bytes: "); foreach(byte b; ba) { printf("%d ", b); } printf(\n); return 1; } Regards, Sjoerd

Read "Setting Dynamic Array Length" here: http://www.digitalmars.com/d/arrays.html Lars Ivar Igesund
Sep 21 2004
prev sibling parent Russ Lewis <spamhole-2001-07-16 deming-os.org> writes:
Lars Ivar Igesund wrote:
 Why do
 
 arr.length = arr.length + 1;
 
 work when
 
 arr.length += 1;
 
 and
 
 arr.length++;
 
 don't ("arr.length is not an lvalue")?
 AFAIK, arr.length is an lvalue in the first statement, too.
 
 Lars Ivar Igesund

This is working as designed (see other posts), but the error message is misleading. I posted a message about it in the bugs newsgroup.
Sep 20 2004