digitalmars.D.bugs - [Issue 3378] New: [tdpl] ++x should be an lvalue
- d-bugmail puremagic.com (24/24) Oct 08 2009 http://d.puremagic.com/issues/show_bug.cgi?id=3378
- d-bugmail puremagic.com (15/17) Oct 09 2009 http://d.puremagic.com/issues/show_bug.cgi?id=3378
- d-bugmail puremagic.com (7/16) Oct 09 2009 http://d.puremagic.com/issues/show_bug.cgi?id=3378
- d-bugmail puremagic.com (10/10) Nov 21 2009 http://d.puremagic.com/issues/show_bug.cgi?id=3378
- d-bugmail puremagic.com (15/16) Nov 22 2009 http://d.puremagic.com/issues/show_bug.cgi?id=3378
- d-bugmail puremagic.com (23/23) Mar 04 2010 http://d.puremagic.com/issues/show_bug.cgi?id=3378
- d-bugmail puremagic.com (17/40) Mar 04 2010 http://d.puremagic.com/issues/show_bug.cgi?id=3378
- d-bugmail puremagic.com (31/31) Mar 04 2010 http://d.puremagic.com/issues/show_bug.cgi?id=3378
- d-bugmail puremagic.com (11/41) Mar 04 2010 http://d.puremagic.com/issues/show_bug.cgi?id=3378
- d-bugmail puremagic.com (34/41) Mar 04 2010 http://d.puremagic.com/issues/show_bug.cgi?id=3378
- d-bugmail puremagic.com (14/59) Mar 04 2010 http://d.puremagic.com/issues/show_bug.cgi?id=3378
- d-bugmail puremagic.com (6/6) Mar 05 2010 http://d.puremagic.com/issues/show_bug.cgi?id=3378
- d-bugmail puremagic.com (6/6) Mar 06 2010 http://d.puremagic.com/issues/show_bug.cgi?id=3378
- d-bugmail puremagic.com (11/11) Mar 08 2010 http://d.puremagic.com/issues/show_bug.cgi?id=3378
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 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: -------
Oct 08 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3378 Don <clugdbug yahoo.com.au> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |clugdbug yahoo.com.au1. The increment is rewritten as x += 1, but it shouldn't as it's a fundamentally different operationFrom 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: -------
Oct 09 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3378 09:09:03 PDT ---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: -------1. The increment is rewritten as x += 1, but it shouldn't as it's a fundamentally different operationFrom 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. "
Oct 09 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3378 Walter Bright <bugzilla digitalmars.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |bugzilla digitalmars.com 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: -------
Nov 21 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3378 17:32:49 PST ---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. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 22 2009
http://d.puremagic.com/issues/show_bug.cgi?id=3378 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: -------
Mar 04 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3378 04:17:15 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.(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: -------
Mar 04 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3378 Steven Schveighoffer <schveiguy yahoo.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |schveiguy yahoo.com 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: -------
Mar 04 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3378 05:12:28 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.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: -------
Mar 04 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3378 06:09:51 PST ---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: -------
Mar 04 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3378 08:03:40 PST ---There's no need to get worried about this, particularly on Walter's behalf (e.g. the cost of implementing the change etc.). We're already past the point where debate is pointless. If there were any advantage in making things an rvalue, keeping TDPL as it is would never be an issue so there's no need to worry about making shady compromises either. Please no generalizations. Clearly this is a minor issue, and clearly there is a marginal gain for making the blessed thing an lvalue. So let's make it an lvalue and worry about larger issues. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------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.
Mar 04 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3378 22:31:41 PST --- changeset 409 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 05 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3378 01:40:56 PST --- changeset 409 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 06 2010
http://d.puremagic.com/issues/show_bug.cgi?id=3378 Walter Bright <bugzilla digitalmars.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |FIXED 22:25:03 PST --- Fixed dmd 2.041 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Mar 08 2010