March 12, 2015
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.
March 12, 2015
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.
March 12, 2015
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

March 14, 2015
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

March 14, 2015
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?
March 14, 2015
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.
March 14, 2015
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.
March 14, 2015
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

March 15, 2015
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


March 15, 2015
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.