www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Post increment and decrement

reply "welkam" <wwwelkam gmail.com> writes:
Observation Nr. 1
People prefer to write var++ instead of ++var.

Observation Nr. 2
Because of observation Nr. 1 and other reasons compilers became 
good at removing code that is not needed making var++ and ++var 
to produce the same code if returned value is not used.

Observation Nr. 3
Because of observation Nr. 2 more people use var++ in place where 
they really only need ++var.

Observation Nr. 4
Because of observation Nr. 3 people learning to program may 
mistakenly learn that var++ is just incrementing. (I am included 
in that list)

Observation Nr. 5
Because of observation Nr. 4 people can write slower than 
necessary code for classes with overloaded operator or even get 
bugs.

Because of all this why not make only one increment/decrement 
operator and have post increment/decrement to be called by 
template name, because it is a template?

template post_inc(T) {
auto tmp = T;
T++;
return tmp;
}
Mar 11 2015
next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 03/11/2015 10:23 AM, welkam wrote:

 Observation Nr. 1
 People prefer to write var++ instead of ++var.

 Observation Nr. 2
 Because of observation Nr. 1 and other reasons compilers became good at
 removing code that is not needed making var++ and ++var to produce the
 same code if returned value is not used.

 Observation Nr. 3
 Because of observation Nr. 2 more people use var++ in place where they
 really only need ++var.

 Observation Nr. 4
 Because of observation Nr. 3 people learning to program may mistakenly
 learn that var++ is just incrementing. (I am included in that list)

 Observation Nr. 5
 Because of observation Nr. 4 people can write slower than necessary code
 for classes with overloaded operator or even get bugs.
+5 for all your observations. (Ok, 5 each, 25 total. :p) I cringe every time I see var++ and var--. That's why I advise against them: http://ddili.org/ders/d.en/arithmetic.html#ix_arithmetic.post-increment
 Because of all this why not make only one increment/decrement operator
 and have post increment/decrement to be called by template name, because
 it is a template?

 template post_inc(T) {
 auto tmp = T;
 T++;
 return tmp;
 }
Agreed but that train has already sailed (: having a good time today); there are too many programs out there doing var++. Ali
Mar 11 2015
parent reply "welkam" <wwwelkam gmail.com> writes:
I should write regex and go trough http://code.dlang.org/ to see 
how many of them  would break if we changed var++ implementation 
to ++var
Mar 11 2015
parent "deadalnix" <deadalnix gmail.com> writes:
On Wednesday, 11 March 2015 at 19:57:15 UTC, welkam wrote:
 I should write regex and go trough http://code.dlang.org/ to 
 see how many of them  would break if we changed var++ 
 implementation to ++var
No.
Mar 11 2015
prev sibling next sibling parent reply "mattcoder" <stop spam.com> writes:
On Wednesday, 11 March 2015 at 17:23:15 UTC, welkam wrote:
 Observation Nr. 1
 People prefer to write var++ instead of ++var.
Believe or not I always used pre-increment. But yes, I see the former in most of the codes out there. Matheus.
Mar 11 2015
parent "mattcoder" <stop spam.com> writes:
On Wednesday, 11 March 2015 at 20:05:03 UTC, mattcoder wrote:
 On Wednesday, 11 March 2015 at 17:23:15 UTC, welkam wrote:
 Observation Nr. 1
 People prefer to write var++ instead of ++var.
Believe or not I always used pre-increment. But yes, I see the former in most of the codes out there.
... and I'm with you! :) Matheus.
Mar 11 2015
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/11/15 10:23 AM, welkam wrote:
 Observation Nr. 1
 People prefer to write var++ instead of ++var.

 Observation Nr. 2
 Because of observation Nr. 1 and other reasons compilers became good at
 removing code that is not needed making var++ and ++var to produce the
 same code if returned value is not used.

 Observation Nr. 3
 Because of observation Nr. 2 more people use var++ in place where they
 really only need ++var.

 Observation Nr. 4
 Because of observation Nr. 3 people learning to program may mistakenly
 learn that var++ is just incrementing. (I am included in that list)

 Observation Nr. 5
 Because of observation Nr. 4 people can write slower than necessary code
 for classes with overloaded operator or even get bugs.

 Because of all this why not make only one increment/decrement operator
 and have post increment/decrement to be called by template name, because
 it is a template?

 template post_inc(T) {
 auto tmp = T;
 T++;
 return tmp;
 }
Observation Nr. 6 Somebody didn't Read The Fine Manual. Page 369: ========= If the result of a++ is not needed, the rewrite is ++a, which is subsequently rewritten to a.opUnary!"++"(). ========= Andrei
Mar 11 2015
parent reply Rikki Cattermole <alphaglosined gmail.com> writes:
On 12/03/2015 1:50 p.m., Andrei Alexandrescu wrote:
 On 3/11/15 10:23 AM, welkam wrote:
 Observation Nr. 1
 People prefer to write var++ instead of ++var.

 Observation Nr. 2
 Because of observation Nr. 1 and other reasons compilers became good at
 removing code that is not needed making var++ and ++var to produce the
 same code if returned value is not used.

 Observation Nr. 3
 Because of observation Nr. 2 more people use var++ in place where they
 really only need ++var.

 Observation Nr. 4
 Because of observation Nr. 3 people learning to program may mistakenly
 learn that var++ is just incrementing. (I am included in that list)

 Observation Nr. 5
 Because of observation Nr. 4 people can write slower than necessary code
 for classes with overloaded operator or even get bugs.

 Because of all this why not make only one increment/decrement operator
 and have post increment/decrement to be called by template name, because
 it is a template?

 template post_inc(T) {
 auto tmp = T;
 T++;
 return tmp;
 }
Observation Nr. 6 Somebody didn't Read The Fine Manual. Page 369: ========= If the result of a++ is not needed, the rewrite is ++a, which is subsequently rewritten to a.opUnary!"++"(). ========= Andrei
+1 Compiler should work for you. This is one of those things it can rewrite to preference. During optimization.
Mar 11 2015
parent reply "Don" <x nospam.com> writes:
On Thursday, 12 March 2015 at 04:06:14 UTC, Rikki Cattermole 
wrote:
 On 12/03/2015 1:50 p.m., Andrei Alexandrescu wrote:
 On 3/11/15 10:23 AM, welkam wrote:
 Observation Nr. 1
 People prefer to write var++ instead of ++var.

 Observation Nr. 2
 Because of observation Nr. 1 and other reasons compilers 
 became good at
 removing code that is not needed making var++ and ++var to 
 produce the
 same code if returned value is not used.

 Observation Nr. 3
 Because of observation Nr. 2 more people use var++ in place 
 where they
 really only need ++var.

 Observation Nr. 4
 Because of observation Nr. 3 people learning to program may 
 mistakenly
 learn that var++ is just incrementing. (I am included in that 
 list)

 Observation Nr. 5
 Because of observation Nr. 4 people can write slower than 
 necessary code
 for classes with overloaded operator or even get bugs.

 Because of all this why not make only one increment/decrement 
 operator
 and have post increment/decrement to be called by template 
 name, because
 it is a template?

 template post_inc(T) {
 auto tmp = T;
 T++;
 return tmp;
 }
Observation Nr. 6 Somebody didn't Read The Fine Manual. Page 369: ========= If the result of a++ is not needed, the rewrite is ++a, which is subsequently rewritten to a.opUnary!"++"(). ========= Andrei
+1 Compiler should work for you. This is one of those things it can rewrite to preference. During optimization.
It doesn't even rely on the optimizer. This happens in the front-end, in the semantic pass.
Mar 12 2015
parent Rikki Cattermole <alphaglosined gmail.com> writes:
On 12/03/2015 9:12 p.m., Don wrote:
 On Thursday, 12 March 2015 at 04:06:14 UTC, Rikki Cattermole wrote:
 On 12/03/2015 1:50 p.m., Andrei Alexandrescu wrote:
 On 3/11/15 10:23 AM, welkam wrote:
 Observation Nr. 1
 People prefer to write var++ instead of ++var.

 Observation Nr. 2
 Because of observation Nr. 1 and other reasons compilers became good at
 removing code that is not needed making var++ and ++var to produce the
 same code if returned value is not used.

 Observation Nr. 3
 Because of observation Nr. 2 more people use var++ in place where they
 really only need ++var.

 Observation Nr. 4
 Because of observation Nr. 3 people learning to program may mistakenly
 learn that var++ is just incrementing. (I am included in that list)

 Observation Nr. 5
 Because of observation Nr. 4 people can write slower than necessary
 code
 for classes with overloaded operator or even get bugs.

 Because of all this why not make only one increment/decrement operator
 and have post increment/decrement to be called by template name,
 because
 it is a template?

 template post_inc(T) {
 auto tmp = T;
 T++;
 return tmp;
 }
Observation Nr. 6 Somebody didn't Read The Fine Manual. Page 369: ========= If the result of a++ is not needed, the rewrite is ++a, which is subsequently rewritten to a.opUnary!"++"(). ========= Andrei
+1 Compiler should work for you. This is one of those things it can rewrite to preference. During optimization.
It doesn't even rely on the optimizer. This happens in the front-end, in the semantic pass.
In our implementation yes. But I'm emphasizing it doesn't have to.
Mar 12 2015
prev sibling next sibling parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Wednesday, 11 March 2015 at 17:23:15 UTC, welkam wrote:
 Observation Nr. 1
 People prefer to write var++ instead of ++var.
The root of your reasoning stems from this "observation", which I argue is wrong. The recommendation has always been to chose ++var, unless you have a reason to chose var++.
 Because of all this why not make only one increment/decrement 
 operator and have post increment/decrement to be called by 
 template name, because it is a template?
Or, instead of creating a new semantic, simply use the existing one. It really isn't that complicated.
Mar 12 2015
parent Nick Treleaven <ntrel-pub mybtinternet.com> writes:
On 12/03/2015 10:14, monarch_dodra wrote:
 On Wednesday, 11 March 2015 at 17:23:15 UTC, welkam wrote:
 Observation Nr. 1
 People prefer to write var++ instead of ++var.
The root of your reasoning stems from this "observation", which I argue is wrong. The recommendation has always been to chose ++var, unless you have a reason to chose var++.
Where the result is not needed, var++ is probably more common. I'd rather read post-increments. Grep -c phobos for simple for loops: ; word++): etc/c/zlib/crc32.c:9 etc/c/zlib/deflate.c:1 etc/c/zlib/gzwrite.c:2 etc/c/zlib/inftrees.c:6 etc/c/zlib/trees.c:25 etc/c/zlib/zutil.c:2 std/algorithm.d:2 std/bitmanip.d:5 std/concurrency.d:1 std/container/rbtree.d:2 std/digest/md.d:1 std/digest/ripemd.d:1 std/digest/sha.d:2 std/math.d:3 std/parallelism.d:1 std/path.d:2 std/random.d:1 std/regex/internal/backtracking.d:3 std/regex/internal/ir.d:1 std/regex/internal/kickstart.d:5 std/regex/internal/parser.d:2 std/regex/internal/tests.d:1 std/regex/package.d:1 std/socket.d:8 std/stream.d:1 std/string.d:2 std/uni.d:18 std/uri.d:11 std/utf.d:3 std/uuid.d:2 std/windows/charset.d:1 std/zip.d:2 std/zlib.d:3 unittest.d:1 ; ++word): std/algorithm.d:8 std/bitmanip.d:1 std/encoding.d:7 std/format.d:4 std/internal/math/biguintcore.d:9 std/internal/math/biguintnoasm.d:17 std/internal/math/biguintx86.d:14 std/internal/math/gammafunction.d:2 std/math.d:1 std/numeric.d:2 std/process.d:3 std/random.d:3 std/stream.d:2 std/utf.d:1 std/windows/registry.d:4 std/xml.d:1
Mar 12 2015
prev sibling next sibling parent "Kagamin" <spam here.lot> writes:
On Wednesday, 11 March 2015 at 17:23:15 UTC, welkam wrote:
 Because of all this why not make only one increment/decrement 
 operator and have post increment/decrement to be called by 
 template name, because it is a template?

 template post_inc(T) {
 auto tmp = T;
 T++;
 return tmp;
 }
That's how it works http://dlang.org/operatoroverloading.html#unary But I see more optimization opportunity here: the result of ++a may be not used too, but it still returns the value, which can be still suboptimal.
Mar 12 2015
prev sibling parent reply Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Wednesday, March 11, 2015 17:23:13 welkam via Digitalmars-d wrote:
 Observation Nr. 1
 People prefer to write var++ instead of ++var.

 Observation Nr. 2
 Because of observation Nr. 1 and other reasons compilers became
 good at removing code that is not needed making var++ and ++var
 to produce the same code if returned value is not used.

 Observation Nr. 3
 Because of observation Nr. 2 more people use var++ in place where
 they really only need ++var.

 Observation Nr. 4
 Because of observation Nr. 3 people learning to program may
 mistakenly learn that var++ is just incrementing. (I am included
 in that list)

 Observation Nr. 5
 Because of observation Nr. 4 people can write slower than
 necessary code for classes with overloaded operator or even get
 bugs.

 Because of all this why not make only one increment/decrement
 operator and have post increment/decrement to be called by
 template name, because it is a template?

 template post_inc(T) {
 auto tmp = T;
 T++;
 return tmp;
 }
Well, much as I hate it when folks use postincrement when preincrement will do, D solved the problem by making it so that they're overloaded with the same operator, so unlike in C++, in D, the compiler is _always_ able to replace a postincrement expression with a preincrement expression if it doesn't matter which is used. So, while I'm in the habit of correcting folks who use i++ when they should use ++i in C++, there really isn't any point in D except insomuch as it will make you a better programmer in other languages if you get into the habit of using preincrement when either will work. - Jonathan M Davis
Mar 13 2015
parent reply "Casper =?UTF-8?B?RsOmcmdlbWFuZCI=?= <shorttail hotmail.com> writes:
What exactly is the downside of i++? Suppose the compiler doesn't 
lower it and I use the expression alone, what is the potential 
damage?
Mar 14 2015
next sibling parent "weaselcat" <weaselcat gmail.com> writes:
On Saturday, 14 March 2015 at 10:11:27 UTC, Casper Færgemand 
wrote:
 What exactly is the downside of i++? Suppose the compiler 
 doesn't lower it and I use the expression alone, what is the 
 potential damage?
AFAIK, there's no guarantee in C/C++ that i++ will be optimized to ++i at all. i++ requires a temporary, this can be trivially optimized away in most cases but an overloaded post-increment can make this much more difficult an example is iterators in C++. Post increment requires you to make a copy of the iterator, increment the current one, and evaluate the copy. Pre-increment just requires you to increment the iterator then evaluate it.(This might not even be true anymore, compilers are pretty smart nowadays.) In D, I don't think it matters that much as already discussed. It's just good form, I believe.
Mar 14 2015
prev sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Saturday, 14 March 2015 at 10:11:27 UTC, Casper Færgemand 
wrote:
 What exactly is the downside of i++? Suppose the compiler 
 doesn't lower it and I use the expression alone, what is the 
 potential damage?
You need to store a temporary of the value pre increment to be returned. But it doesn't matter as any compiler will optimize it away if you don't use it. But, for some reason, the topic come up again and again from C++ devs that have no idea the optimization guys solved the issues for years now.
Mar 14 2015
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 03/14/2015 03:23 PM, deadalnix wrote:

 But, for some reason, the topic come up again and again from C++ devs
 that have no idea the optimization guys solved the issues for years now.
If we are talking about C++, it is not possible to not take that copy for user-defined types. Due to separate compilation, the compiler does not even see the definition of operator++(int). And the compiler cannot replace calls to operator++(int) with calls to operator++() (when the return value is not used) because the programmer may have done different things than the canonical implmentation of post-increment. C++ needs a rule like D's, which will never be there. Ali
Mar 14 2015
parent reply Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Saturday, March 14, 2015 15:35:24 Ali ehreli via Digitalmars-d wrote:
 On 03/14/2015 03:23 PM, deadalnix wrote:

  > But, for some reason, the topic come up again and again from C++ devs
  > that have no idea the optimization guys solved the issues for years now.

 If we are talking about C++, it is not possible to not take that copy
 for user-defined types. Due to separate compilation, the compiler does
 not even see the definition of operator++(int).

 And the compiler cannot replace calls to operator++(int) with calls to
 operator++() (when the return value is not used) because the programmer
 may have done different things than the canonical implmentation of
 post-increment.
Exactly. In C++, there isn't even a guarantee than an overloaded postincrement operator is even related to an overloaded preincrement operator. One could do addition while the other does subtraction - or nothing at all. Sure, bad code won't do that, but the compiler doesn't know whether you're being an idiot or not. So, it can't assume that overloaded preincrement and postincrement are at all related and therefore can't optimize a postincrement to a preincrement for overloaded operators. The result is that simply always using preincrement when you need to increment but don't specifically need to postincrement is a good habit to get into. Its impact is likely to be minimal in most cases, but it doesn't cost you anything, and you can't rely on the compiler's ability to optimize, because the C++ standards committee didn't restrict the overloaded increment (or decrement) operators enough to enable the compiler to optimize them properly.
 C++ needs a rule like D's, which will never be there.
Yep. By making it so that you only overload a single operator for both versions of increment, we avoid the whole problem in D, similar to how having opCmp avoids bugs related to having to define each comparison operator individually as is the case in C++. It'll likely always bug me though when I see i++ when ++i would work, even if it doesn't matter in D. It's just too ingrained in me, I guess. :) - Jonathan M Davis
Mar 15 2015
next sibling parent reply "Kagamin" <spam here.lot> writes:
On Sunday, 15 March 2015 at 08:45:55 UTC, Jonathan M Davis wrote:
 cost you anything, and you can't rely on the compiler's ability 
 to optimize
If you want performance and can't rely on optimizations, you can only use assembler.
 because the C++ standards committee didn't restrict the 
 overloaded increment
 (or decrement) operators enough to enable the compiler to 
 optimize them
 properly.
Optimizer optimizes any code, it doesn't matter, what the code does.
Mar 15 2015
parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Sun, 15 Mar 2015 19:34:11 +0000, Kagamin wrote:

 Optimizer optimizes any code, it doesn't matter, what the code does.
wow! i wrote an excellect optimizer yesterday. it optimizes any code to=20 `nop`...=
Mar 15 2015
parent reply "Kagamin" <spam here.lot> writes:
On Sunday, 15 March 2015 at 19:39:06 UTC, ketmar wrote:
 wow! i wrote an excellect optimizer yesterday. it optimizes any 
 code to
 `nop`...
Why, rm didn't work for you?
Mar 15 2015
parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Sun, 15 Mar 2015 19:46:39 +0000, Kagamin wrote:

 On Sunday, 15 March 2015 at 19:39:06 UTC, ketmar wrote:
 wow! i wrote an excellect optimizer yesterday. it optimizes any code to
 `nop`...
=20 Why, rm didn't work for you?
no. it removes code, and i want to optimize code.=
Mar 15 2015
parent reply "welkam" <wwwelkam gmail.com> writes:
Here is some data.

vibe.d

foreach:
505 matches across 74 files
++var:
15 matches across 8 files
var++:
168 matches across 37 files
20 would brake if changed meaning to ++var

deadcode (IDE)

foreach:
366 matches across 68 files
++var:
62 matches across 10 files
var++:
111 matches across 30 files
17 would brake if changed meaning to ++var

phobos

foreach:
2007 matches across 77 files
++var:
508 matches across 59 files
var++;
1579 matches across 90 files
N/A would brake if changed meaning to ++var

DMD

foreach:
1338 matches across 219 files
++var:
564 matches across 139 files
var++;
3285 matches across 292 files
N/A would brake if changed meaning to ++var

foreach number was obtained by using find string algorithm
var++ number was obtained by using regex 
([^\;\s\+\(\)\]\,\"]+)\+\+
++var number was obtained by using regex 
\+\+([^\;\s\+\(\)\]\,\"]+)
Mar 20 2015
next sibling parent reply "deadalnix" <deadalnix gmail.com> writes:
On Friday, 20 March 2015 at 21:56:44 UTC, welkam wrote:
 Here is some data.

 vibe.d

 foreach:
 505 matches across 74 files
 ++var:
 15 matches across 8 files
 var++:
 168 matches across 37 files
 20 would brake if changed meaning to ++var

 deadcode (IDE)

 foreach:
 366 matches across 68 files
 ++var:
 62 matches across 10 files
 var++:
 111 matches across 30 files
 17 would brake if changed meaning to ++var

 phobos

 foreach:
 2007 matches across 77 files
 ++var:
 508 matches across 59 files
 var++;
 1579 matches across 90 files
 N/A would brake if changed meaning to ++var

 DMD

 foreach:
 1338 matches across 219 files
 ++var:
 564 matches across 139 files
 var++;
 3285 matches across 292 files
 N/A would brake if changed meaning to ++var

 foreach number was obtained by using find string algorithm
 var++ number was obtained by using regex 
 ([^\;\s\+\(\)\]\,\"]+)\+\+
 ++var number was obtained by using regex 
 \+\+([^\;\s\+\(\)\]\,\"]+)
Now end up you data gathering : Turn them around (sed can do that for you), recompile, benchmark, and see that it does not change anything at the end.
Mar 20 2015
parent reply "welkam" <wwwelkam gmail.com> writes:
On Friday, 20 March 2015 at 22:01:35 UTC, deadalnix wrote:
 Now end up you data gathering :

 Turn them around (sed can do that for you), recompile, 
 benchmark, and see that it does not change anything at the end.
I do not know exact implementation of D compiler but I guess it generates code and then optimises it away. If thats the case then you slow down your compilation unnecessarily. Also having language construct that is being used only 15% of the time correctly is not great. And D has foreach. In C++ world this is even worse. Is this a big problem? Not really, but its still a problem.
Mar 20 2015
next sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Friday, 20 March 2015 at 22:52:54 UTC, welkam wrote:
 On Friday, 20 March 2015 at 22:01:35 UTC, deadalnix wrote:
 Now end up you data gathering :

 Turn them around (sed can do that for you), recompile, 
 benchmark, and see that it does not change anything at the end.
I do not know exact implementation of D compiler but I guess it generates code and then optimises it away. If thats the case then you slow down your compilation unnecessarily.
You can include measurement of compile time in your benchmark.
 Also having language construct that is being used only 15% of 
 the time correctly is not great. And D has foreach. In C++ 
 world this is even worse.

 Is this a big problem? Not really, but its still a problem.
I'm waiting the numbers that support this assertion with great impatience.
Mar 20 2015
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/20/15 3:52 PM, welkam wrote:
 On Friday, 20 March 2015 at 22:01:35 UTC, deadalnix wrote:
 Now end up you data gathering :

 Turn them around (sed can do that for you), recompile, benchmark, and
 see that it does not change anything at the end.
I do not know exact implementation of D compiler but I guess it generates code and then optimises it away. If thats the case then you slow down your compilation unnecessarily. Also having language construct that is being used only 15% of the time correctly is not great. And D has foreach. In C++ world this is even worse. Is this a big problem? Not really, but its still a problem.
Are you sure you're not missing the part where D's ++var and var++ generate identical code if the result isn't taken? -- Andrei
Mar 20 2015
parent reply "welkam" <wwwelkam gmail.com> writes:
On Saturday, 21 March 2015 at 00:42:22 UTC, Andrei Alexandrescu 
wrote:
 Are you sure you're not missing the part where D's ++var and 
 var++ generate identical code if the result isn't taken? -- 
 Andrei
No I am not missing it. I think I need to explain why I am doing all of this. I am currently looking for rules and programming styles that would reduce number of bugs and/or make my program run or at least compile faster. So I read that you should prefer pre increment to post increment. So I investigate and concluded that for the most part it doesn't matter. But that "most if the time" thing bugged me over a month. I investigated more and I was jumping constantly between it matters and it doesn't matter. Every time I jump to it matters the amount of matters shrinks. So now I am on the quest to quantify how much it matters and if it doesnt matter I could say to anybody who repeats it to eat a bowl of dicks. In C++ world always writing ++var can save some perf when using with overloaded operators. In D world it has no result on resulting binary and the use of these operators is reduced with foreach.
Mar 21 2015
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/21/15 9:59 AM, welkam wrote:
 On Saturday, 21 March 2015 at 00:42:22 UTC, Andrei Alexandrescu wrote:
 Are you sure you're not missing the part where D's ++var and var++
 generate identical code if the result isn't taken? -- Andrei
No I am not missing it. I think I need to explain why I am doing all of this. I am currently looking for rules and programming styles that would reduce number of bugs and/or make my program run or at least compile faster. So I read that you should prefer pre increment to post increment.
That's only for generic C++ code. At a minimum you're in the wrong forum. Also as I said, using post operations for integrals may be faster, so even in C++ it's not that clear cut. Andrei
Mar 21 2015
prev sibling parent reply "Kagamin" <spam here.lot> writes:
On Saturday, 21 March 2015 at 16:59:05 UTC, welkam wrote:
 In C++ world always writing ++var can save some perf when using 
 with overloaded operators.
Do you have an example?
Mar 23 2015
parent reply "krzaq" <dlangmailinglist krzaq.cc> writes:
On Monday, 23 March 2015 at 08:20:59 UTC, Kagamin wrote:
 On Saturday, 21 March 2015 at 16:59:05 UTC, welkam wrote:
 In C++ world always writing ++var can save some perf when 
 using with overloaded operators.
Do you have an example?
The compiler cannot optimize away calls to external functions (such as operator new, as is my experience) that it cannot inline/see fully (I may be not 100% correct here, but I'm pretty sure it's in the right ballpark). Here's an example, compare foo() and bar() (note the -O3): http://goo.gl/H9tCaK
Mar 23 2015
parent reply "Kagamin" <spam here.lot> writes:
Well, things like std::string are not cooperative in this regard. 
Though, it's copied only to be instantly destructed, 
theoretically it should be elided if the involved constructors 
are annotated with sufficient purity or complementary operators. 
Also the iterator pretends to be copyable, but it can't resume 
from the point where it was copied, can it?
Mar 23 2015
parent "krzaq" <dlangmailinglist krzaq.cc> writes:
On Monday, 23 March 2015 at 12:10:32 UTC, Kagamin wrote:
 Well, things like std::string are not cooperative in this 
 regard. Though, it's copied only to be instantly destructed, 
 theoretically it should be elided if the involved constructors 
 are annotated with sufficient purity or complementary operators.
That's why using preincrementation is the preferred default - you simply can't know predict what the user's type will do. And sure, maybe the compiler should optimize it away in this case, but as you can see, the pragmatic solution is to simply avoid this problem entirely.
 Also the iterator pretends to be copyable, but it can't resume 
 from the point where it was copied, can it?
Depends on the iterator type, in this case: no, I don't believe that it can be resumed.
Mar 23 2015
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 3/20/15 2:56 PM, welkam wrote:
 Here is some data.
[snip] Actually var++ is more efficient than ++var for integrals. I cover that in one of my optimization talks available publicly. -- Andrei
Mar 20 2015
prev sibling next sibling parent "deadalnix" <deadalnix gmail.com> writes:
On Sunday, 15 March 2015 at 08:45:55 UTC, Jonathan M Davis wrote:
 On Saturday, March 14, 2015 15:35:24 Ali Çehreli via 
 Digitalmars-d wrote:
 On 03/14/2015 03:23 PM, deadalnix wrote:

  > But, for some reason, the topic come up again and again 
 from C++ devs
  > that have no idea the optimization guys solved the issues 
 for years now.

 If we are talking about C++, it is not possible to not take 
 that copy
 for user-defined types. Due to separate compilation, the 
 compiler does
 not even see the definition of operator++(int).

 And the compiler cannot replace calls to operator++(int) with 
 calls to
 operator++() (when the return value is not used) because the 
 programmer
 may have done different things than the canonical 
 implmentation of
 post-increment.
Exactly. In C++, there isn't even a guarantee than an overloaded postincrement operator is even related to an overloaded preincrement operator. One could do addition while the other does subtraction - or nothing at all. Sure, bad code won't do that, but the compiler doesn't know whether you're being an idiot or not. So, it can't assume that overloaded preincrement and postincrement are at all related and therefore can't optimize a postincrement to a preincrement for overloaded operators. The result is that simply always using preincrement when you need to increment but don't specifically need to postincrement is a good habit to get into. Its impact is likely to be minimal in most cases, but it doesn't cost you anything, and you can't rely on the compiler's ability to optimize, because the C++ standards committee didn't restrict the overloaded increment (or decrement) operators enough to enable the compiler to optimize them properly.
 C++ needs a rule like D's, which will never be there.
Yep. By making it so that you only overload a single operator for both versions of increment, we avoid the whole problem in D, similar to how having opCmp avoids bugs related to having to define each comparison operator individually as is the case in C++. It'll likely always bug me though when I see i++ when ++i would work, even if it doesn't matter in D. It's just too ingrained in me, I guess. :) - Jonathan M Davis
Yeah, one can rationalize all he/she wants. Thing is: - Either the operator implementation is simple and the optimizer will see through it. - Or it is quite complex and the extra copy will barely show up in benchmark anyway. The only case where it makes sense is with separate compilation, as Ali mentioned. But in which case, same as above, either the thing is simple, and you loose way more in calling convention than you could save by optimizing a copy away, or the implementation is complex so that the calling convention or the extra copy do not matter.
Mar 15 2015
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 3/15/2015 1:45 AM, Jonathan M Davis via Digitalmars-d wrote:
 On Saturday, March 14, 2015 15:35:24 Ali Çehreli via Digitalmars-d wrote:
 C++ needs a rule like D's, which will never be there.
Yep. By making it so that you only overload a single operator for both versions of increment, we avoid the whole problem in D, similar to how having opCmp avoids bugs related to having to define each comparison operator individually as is the case in C++.
There's another reason why D specifies some arithmetic identities for overloading arithmetic operators. It's to make abominations like C++ iostreams that overload operators for non-arithmetic tasks much harder to do.
Mar 22 2015