14 Nov, 2009, KaVir wrote in the 21st comment:
Votes: 0
David Haley said:
Well, yes. That doesn't mean that it's always impossible to simply look at the generated code and deduce that the created object is useless, and that the creation process is side-effect free, and therefore can be skipped.

You're talking about some very big "maybes" here - RVO might get you down to one temporary object, but I find it highly unlikely that an initialised and returned object would be skipped entirely, particularly if there were some cases in the software where you did want the return value of that function.

But either way, this is a very different situation to the simple (and fairly clear-cut) postfix/prefix optimisation performed on integral types. The point still remains that if you're using overloaded operators, you should favour prefix over postfix.
14 Nov, 2009, David Haley wrote in the 22nd comment:
Votes: 0
KaVir said:
particularly if there were some cases in the software where you did want the return value of that function

I'm not sure why what happens in other places affects what happens in one particular place. This kind of optimization doesn't work that way.

KaVir said:
But either way, this is a very different situation to the simple (and fairly clear-cut) postfix/prefix optimisation performed on integral types.

Yes, I agree; I never said that things were exactly the same as with the primitive (non-overloaded) integral type operators.

KaVir said:
The point still remains that if you're using overloaded operators, you should favour prefix over postfix.

I agreed in post #2 that when necessary I use prefix over postfix. I have also stated that most of the time it's irrelevant, although I also stated that overloaded operators can do some kind of fishy things and people should be careful with those. I'm not entirely sure which specific point I've made you're disagreeing with.
14 Nov, 2009, KaVir wrote in the 23rd comment:
Votes: 0
David Haley said:
I'm not sure why what happens in other places affects what happens in one particular place.

Because you're talking about the compiler literally ignoring the construction, copying and destruction of a returned object if it's not used (can it even do that without breaking the as-if rule?). If it is used in other places then the compiler would need to produce two versions of the function, unless it was inlining the code each time.

Can you give me any example of a C++ compiler that optimises code in the way you've suggested? You could check it easily enough just by adding a counter in the copy constructor.
14 Nov, 2009, David Haley wrote in the 24th comment:
Votes: 0
KaVir said:
You could check it easily enough just by adding a counter in the copy constructor.

…and this would not longer be optimizing in the way I've suggested, because there are now side effects (namely, incrementing the counter). Optimizing this away would indeed be quite incorrect.

To answer your question, no, I don't know of any compiler that does this specifically, because I don't keep track of which ones optimize in which way. I'd point you to post #20 in which I already addressed this question, too.
14 Nov, 2009, Tyche wrote in the 25th comment:
Votes: 0
KaVir said:
David Haley said:
I'm not sure why what happens in other places affects what happens in one particular place.

Because you're talking about the compiler literally ignoring the construction, copying and destruction of a returned object if it's not used (can it even do that without breaking the as-if rule?). If it is used in other places then the compiler would need to produce two versions of the function, unless it was inlining the code each time.

Can you give me any example of a C++ compiler that optimises code in the way you've suggested? You could check it easily enough just by adding a counter in the copy constructor.


Placing a counter in the copy constructor would presumably prevent optimization.
It's easy enough to prove one way or the other by simply looking at the machine code generated in a debugger.

Clearly for integrals the optimization is rather dramatic.
For instance

int main() {x = 10;++x;x++;return x;}

Is optimized that the compiler just pushes 12 in the accumulator and returns.

Well the point of my first post is that nobody has to guess at this, or accept myths about what the compiler will or won't optimize.
The answer is can be obtained right at your console.
14 Nov, 2009, KaVir wrote in the 26th comment:
Votes: 0
David Haley said:
To answer your question, no, I don't know of any compiler that does this specifically

Well until you do, I'm going to stand by the comments I made in my first post.

Tyche said:
Clearly for integrals the optimization is rather dramatic.

To be fair I did already mention that in post #10, #14, #18 and #21. What I'm disagreeing with is the suggestion that the choice of prefix/postfix doesn't matter when applied to objects with overloaded prefix and postfix operators.
15 Nov, 2009, David Haley wrote in the 27th comment:
Votes: 0
Nobody has stated that the choice of prefix/postfix never matters when applied to objects with overloaded prefix and postfix operators, KaVir. I'm not sure who you're arguing with. I asked in #22 which point specifically I made you're disagreeing with, and it's still unclear to me.
15 Nov, 2009, KaVir wrote in the 28th comment:
Votes: 0
David Haley said:
Nobody has stated that the choice of prefix/postfix never matters when applied to objects with overloaded prefix and postfix operators, KaVir. I'm not sure who you're arguing with. I asked in #22 which point specifically I made you're disagreeing with, and it's still unclear to me.

In my first post I pointed out that while using the postfix operator on integral types didn't matter, the same argument wasn't true for objects. You flat-out disagreed with me, so I've been explained my reasoning since then.

Are you now claiming that actually you didn't disagree with me at all? If so, what exactly was the purpose of all your posts?

You have this really annoying habit of strongly disagreeing with people and aggressively arguing your case - then when you realise your argument doesn't hold up, you suddenly pretend that actually you didn't disagree with them at all. I thought you'd turned over a new leaf after Samson was driven off, but it seems you're back to your old ways again. It makes it very difficult to hold any sort of worthwhile discussion with you.
15 Nov, 2009, David Haley wrote in the 29th comment:
Votes: 0
In the post you refer to, I disagreed with your statement that the compiler has no way of knowing what the operators are doing. In particular,

David Haley said:
KaVir said:
but it can't do the same for objects with their own overloaded operators, because it doesn't know what those operators will do.

Well, it kind of does – in fact it knows exactly what the operators will do. What those operators do, however, might be complex enough that it doesn't know how to optimize them.


You seem to think that just because I disagree with some particular point – namely that the compiler has 'no way of knowing what's going on' – that I'm saying that absolutely everything you say is wrong. This is very bizarre considering that I stated your general point in post #2 of this thread. I can agree with your general point while disagreeing with a particular aspect of that point; is that unsatisfactory to you?

I find it unfortunate that you say I'm "suddenly pretending that actually <I> didn't disagree", whereas in reality – if the post record is of any importance to you, at least – I have been making the same general point from the very beginning. I have said this several times, and even asked you very directly to point out specifically what you disagreed with. You never really answered, and now you come out with personal attacks. It's like you're trying to make a fight out of this, trying to turn what would otherwise be a small disagreement (incidentally, don't pretend that you don't "aggressively argue your case" either) into a much larger fight. Actually, I'll correct that: you have succeeded in making this into a much bigger deal than it should have been.

Speaking of which, I also find it unfortunate that you chose to make a personal issue out of this. I'm not entirely sure why you seem to think that all fault (if indeed there is any "fault" here) lies in my hands. In any event, hopefully any confusion has been cleared up now.
15 Nov, 2009, Mudder wrote in the 30th comment:
Votes: 0
You guys are such nerds. I love you all. You can take a difference in coding style and turn it into a passionate argument. :robot:
15 Nov, 2009, Runter wrote in the 31st comment:
Votes: 0
They <3 a good argument.
16 Nov, 2009, Kaz wrote in the 32nd comment:
Votes: 0
Yes, the compiler might optimise away the unused temporary from the postfix operator++. We can generalise from this, though:

Where prefix and postfix operators perform the same task, prefix is at least as efficient as postfix, and postfix is at most as efficient as prefix (depending on optimisations).

Therefore, the Best Practice would be to use prefix where you can, and postfix where you must.
20.0/32