Why does postfix operator++ have higher precedence

2019-02-16 14:58发布

问题:

Defined this way, we can do neither ++x++ nor ++x--. But on the other hand, both (++x)++ and (++x)-- are useful expressions: (++x)++ increments x by two and returns the value "in the middle", while (++x)-- is essentially equivalent to x+1 but completely avoids having to call operator+, which can be quite useful sometimes.

So why is the precedence not defined to have ++x++ automatically expand to (++x)++ rather than ++(x++)? Is there some hidden meaning to the latter which I don't understand, or is it just to keep the precedence a simple list with all prefix operators making up one single level?

EDIT Ok, I didn't explicitly say it, but: of course I meant x to be user-defined type. For built-in types, (x+=2)-1 is of course better than (++x)++, and x+1 is a lot better than (++x)--. The situation that I have in mind is an iterator to a rather complicated type of semi-associative container, where operators += and + (being designed for random access) have to rebuild a cache in order to work efficiently for general requests, and are therefore an order of magnitude slower than ++. But of course I can modify them to always check first if the argument is a very small integer, and in that case just call operator++ repeatedly instead of doing the random-access procedure. That should work fine here, though I could imagine I might at some point have a situation in which I want operator+= to always go the random-access way, regardless of how small numbers I present it.


So... for me, I would conclude the answer to be:

the advantage of having a simple and well-memorizeable precedence list in which all postfix operators come before any of the prefix operators is sufficient to tolerate the minor drawback of always having to use parentheses to compose pre- and postfix operators ++/--, as this composition is used very seldom.

The simpler "C does it this way", while it seems likely to be the real reason, is far less satisfying in to me, because since ++x++ was not allowed at all in C it would have been possible to redefine this very composition without damaging any existing code.

Anyway, I will go on using (++x)--, as the parentheses really do not hurt so much.

回答1:

C++ standard just kept the C rules and obviously those weren't fixed considering operator overloading and idioms yet be invented in a yet to be invented language.

Looking at what is available in D.M. Ritchie Home Page, on see that this precedence is already present in B (Unary operators are bound right to left. Thus -!x++ is bound -(!(x++)) in Users' Reference to B) and I didn't see increment operators in BCPL.



回答2:

(++x)++ increments x by two and returns the value "in the middle"

Why not (x += 2) - 1 or (++x, x++)? Both seem to be clearer. For scalars, both are well-defined also in C++03, as opposed to your proposed expression.


(++x)-- is essentially equivalent to x+1 but completely avoids having to call operator+, which can be quite useful sometimes.

That's an arbitrary statement without any explanation. So I'm going to throw into the pool:

x+1 is essentially equivalent to (++x)-- but completely avoids having to call operator++ and operator-- which can be useful sometimes.


So why is the precedence not defined to have ++x++ automatically expand to (++x)++ rather than ++(x++)

Just to make such arcane corner cases not error out? No way. Can you please recite man operator for me? If you cannot do that, better not try and write ++x++ in your code.



回答3:

Both (++x)++ and (++x)-- invoke undefined behaviour [assuming x to be a primitive type]. For user defined type the scenario would be different. However it is not generally recommended to use such confusing expressions in your code.

As far as the precendence is concerned this answer explains why post increment has higher precedence than pre increment.