Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
October 08, 2009 [Issue 3378] New: [tdpl] ++x should be an lvalue | ||||
---|---|---|---|---|
| ||||
http://d.puremagic.com/issues/show_bug.cgi?id=3378 Summary: [tdpl] ++x should be an lvalue Product: D Version: unspecified Platform: Other OS/Version: Linux Status: NEW Severity: normal Priority: P2 Component: DMD AssignedTo: nobody@puremagic.com ReportedBy: andrei@metalanguage.com --- Comment #0 from Andrei Alexandrescu <andrei@metalanguage.com> 2009-10-08 14:12:33 PDT --- This doesn't compile: ref int bump(ref int x) { return ++x; } The error message reveals two other issues: Error: x += 1 is not an lvalue 1. The increment is rewritten as x += 1, but it shouldn't as it's a fundamentally different operation 2. x += 1 is not a value itself. Indeed this doesn't compile either: ref int bump(ref int x) { return x += 1; } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
October 09, 2009 [Issue 3378] [tdpl] ++x should be an lvalue | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | http://d.puremagic.com/issues/show_bug.cgi?id=3378 Don <clugdbug@yahoo.com.au> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |clugdbug@yahoo.com.au --- Comment #1 from Don <clugdbug@yahoo.com.au> 2009-10-09 06:37:38 PDT --- (In reply to comment #0) > 1. The increment is rewritten as x += 1, but it shouldn't as it's a fundamentally different operation From the spec: " Overloading ++e and --e Since ++e is defined to be semantically equivalent to (e += 1), the expression ++e is rewritten as (e += 1), and then checking for operator overloading is done. " -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
October 09, 2009 [Issue 3378] [tdpl] ++x should be an lvalue | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | http://d.puremagic.com/issues/show_bug.cgi?id=3378 --- Comment #2 from Andrei Alexandrescu <andrei@metalanguage.com> 2009-10-09 09:09:03 PDT --- (In reply to comment #1) > (In reply to comment #0) > > 1. The increment is rewritten as x += 1, but it shouldn't as it's a fundamentally different operation > > From the spec: " > Overloading ++e and --e > Since ++e is defined to be semantically equivalent to (e += 1), the expression > ++e is rewritten as (e += 1), and then checking for operator overloading is > done. " I know, I know! That spec must be definitely changed. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
November 21, 2009 [Issue 3378] [tdpl] ++x should be an lvalue | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | http://d.puremagic.com/issues/show_bug.cgi?id=3378 Walter Bright <bugzilla@digitalmars.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |bugzilla@digitalmars.com --- Comment #3 from Walter Bright <bugzilla@digitalmars.com> 2009-11-21 02:16:15 PST --- I guess, why? Why does ++x need to be an lvalue? -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
November 23, 2009 [Issue 3378] [tdpl] ++x should be an lvalue | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | http://d.puremagic.com/issues/show_bug.cgi?id=3378 --- Comment #4 from Andrei Alexandrescu <andrei@metalanguage.com> 2009-11-22 17:32:49 PST --- (In reply to comment #3) > I guess, why? Why does ++x need to be an lvalue? 1. It's a departure from C. If we do make that departure, we need a good reason, which I don't know of. (Before you reply with that, I do remember you mentioned that dmc yields an rvalue and no client every filed a bug.) 2. For most user-defined types returning a value is considerably more expensive than returning a reference and nontrivial to remove for the compiler when unused (requires context sensitivity). If built-ins return an rvalue and user-defined return a reference, generic code will be gratuitously incompatible across such types. For me reason #2 is the more important. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 04, 2010 [Issue 3378] [tdpl] ++x should be an lvalue | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | http://d.puremagic.com/issues/show_bug.cgi?id=3378 --- Comment #5 from Walter Bright <bugzilla@digitalmars.com> 2010-03-04 02:40:29 PST --- C99 says this about ++x: -------6.5.3.1------------- The operand of the prefix increment or decrement operator shall have qualified or unqualified real or pointer type and shall be a modifiable lvalue. Semantics The value of the operand of the prefix ++ operator is incremented. The result is the new value of the operand after incrementation. The expression ++E is equivalent to (E+=1). See the discussions of additive operators and compound assignment for information on constraints, types, side effects, and conversions and the effects of operations on pointers. The prefix -- operator is analogous to the prefix ++ operator, except that the value of the operand is decremented. --------6.5.16------------------- An assignment expression has the value of the left operand after the assignment, but is not an lvalue. --------------------------------- It is equivalent to x+=1, and therefore not an lvalue. The C++98 spec also says that ++x is equivalent to x+=1, but says that the result of x+=1 is an lvalue. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 04, 2010 [Issue 3378] [tdpl] ++x should be an lvalue | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | http://d.puremagic.com/issues/show_bug.cgi?id=3378 --- Comment #6 from Andrei Alexandrescu <andrei@metalanguage.com> 2010-03-04 04:17:15 PST --- (In reply to comment #5) > C99 says this about ++x: > > -------6.5.3.1------------- > The operand of the prefix increment or decrement operator shall have qualified or unqualified real or pointer type and shall be a modifiable lvalue. > > Semantics > > The value of the operand of the prefix ++ operator is incremented. The result is the new value of the operand after incrementation. The expression ++E is equivalent to (E+=1). See the discussions of additive operators and compound assignment for information on constraints, types, side effects, and conversions and the effects of operations on pointers. The prefix -- operator is analogous to the prefix ++ operator, except that the value of the operand is decremented. > --------6.5.16------------------- > An assignment expression has the value of the left operand after the assignment, but is not an lvalue. > --------------------------------- > > It is equivalent to x+=1, and therefore not an lvalue. > > The C++98 spec also says that ++x is equivalent to x+=1, but says that the result of x+=1 is an lvalue. (Still scantily connected.) Wait, I'm confused. C and C++ do not define ++x as x+=1, right? We shouldn't either, for reasons that we've discussed at length before (i.e. there are UDTs for which increment makes sense but addition does not.) So: (a) x+=1 is not a part of the discussion about ++x. (b) Keeping ++x an rvalue is a gratuitous incompatibility with C and C++ (c) Keeping ++x an rvalue requires extensive rework of TDPL (the bump example is taken from there) There isn't much reason to debate. It's a trivial change that has only benefits (albeit minor), I suggest we simply make it and move on. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 04, 2010 [Issue 3378] [tdpl] ++x should be an lvalue | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | http://d.puremagic.com/issues/show_bug.cgi?id=3378 Steven Schveighoffer <schveiguy@yahoo.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |schveiguy@yahoo.com --- Comment #7 from Steven Schveighoffer <schveiguy@yahoo.com> 2010-03-04 04:33:04 PST --- testing: [steves@steveslaptop ~]$ cat testit.c int x; int * foo() { return &(++x); } [steves@steveslaptop ~]$ gcc -c testit.c testit.c: In function ‘foo’: testit.c:4: error: lvalue required as unary ‘&’ operand [steves@steveslaptop ~]$ g++ -c testit.c [steves@steveslaptop ~]$ So, C (at least in gcc) does not consider ++x an lvalue, C++ (g++) does. This is consistent with what Walter says. Choosing one or the other is arbitrarily right or wrong depending on what compatibility you wish to have. I agree that defining ++x to be equivalent x+=1 for all types of x is bad, but defining it that way for builtins is fine. I don't see a huge benefit to having ++x return an lvalue. Why can't you rewrite bump like so? ref int bump(ref int x) { ++x; return x;} This should work for all types of x. In practice, I don't think using ++x as an lvalue comes up much. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 04, 2010 [Issue 3378] [tdpl] ++x should be an lvalue | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | http://d.puremagic.com/issues/show_bug.cgi?id=3378 --- Comment #8 from Andrei Alexandrescu <andrei@metalanguage.com> 2010-03-04 05:12:28 PST --- (In reply to comment #7) > testing: > > [steves@steveslaptop ~]$ cat testit.c > int x; > int * foo() > { > return &(++x); > } > [steves@steveslaptop ~]$ gcc -c testit.c > testit.c: In function ‘foo’: > testit.c:4: error: lvalue required as unary ‘&’ operand > [steves@steveslaptop ~]$ g++ -c testit.c > [steves@steveslaptop ~]$ > > So, C (at least in gcc) does not consider ++x an lvalue, C++ (g++) does. > > This is consistent with what Walter says. Choosing one or the other is arbitrarily right or wrong depending on what compatibility you wish to have. > > I agree that defining ++x to be equivalent x+=1 for all types of x is bad, but defining it that way for builtins is fine. > > I don't see a huge benefit to having ++x return an lvalue. Why can't you rewrite bump like so? > > ref int bump(ref int x) { ++x; return x;} > > This should work for all types of x. > > In practice, I don't think using ++x as an lvalue comes up much. I can't rewrite bump because it's part of a large example illustrating ref. The book is in copyediting now and I must limit changes as much as possible. All other things equal, lvalue is better because there's less rewrite needed. One extra point to keep in mind: making ++x an lvalue makes compatible implementations for UDTs' ++ cheaper. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
March 04, 2010 [Issue 3378] [tdpl] ++x should be an lvalue | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | http://d.puremagic.com/issues/show_bug.cgi?id=3378 --- Comment #9 from Steven Schveighoffer <schveiguy@yahoo.com> 2010-03-04 06:09:51 PST --- (In reply to comment #8) > > I can't rewrite bump because it's part of a large example illustrating ref. I don't wish to have a largeish debate about this, but this is not a good reason. My rewritten version illustrates ref just as well. The only difference between mine and yours is that yours illustrates that ++x is an lvalue. > The > book is in copyediting now and I must limit changes as much as possible. All > other things equal, lvalue is better because there's less rewrite needed. Less rewrite of the book, more rewrite of the compiler. It's a shame we have to make a decision based on this. That being said, you stated before there would be more changes needed in the book. Can we get an idea of how much of a rewrite we are talking about? > One extra point to keep in mind: making ++x an lvalue makes compatible implementations for UDTs' ++ cheaper. Making ++x an lvalue would still be possible with UDTs, you can return whatever you wish from a custom operator. Even if ++x is an lvalue for builtins it still will be possible to make ++x an rvalue for UDTs. Returning an lvalue from a UDT is most likely not because it should be used as an lvalue, but more likely because returning an lvalue performs better. This consideration has little or no bearing on ++x for builtins. In other words, the fact that UDTs return an lvalue is a side effect that maybe shouldn't really be exploited in generic code. Superficially, all operators that return classes return lvalues, i.e. for a class A that returns an A on addition and supports assignment from an int will support something like: a + a = 5; which doesn't make any sense for value types, but should we make addition of two integers return an lvalue for the sake of generic programming so such statements always compile? I think we should stop debating about the generic term ++x being an lvalue and focus on whether ++x should be an lvalue for builtin types, simply because the compiler does not control the lvalueness of ++x for UDTs. When you look at it that way, it's simply a judgement call. I'm not saying I'm against changing the behavior, it just seems like an insignificant change to me. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- |
Copyright © 1999-2021 by the D Language Foundation