¿Por qué hay un prefijo / sufijo ++ pero no un prefijo / sufijo + =?

This may seem like a silly question, but why is it that in many languages there exists a prefix and postfix version of the ++ y -- operator, but no similar prefix/postfix versions of other operators like += or -=? For example, it seems like if I can write this code:

myArray[x++] = 137; // Write 137 to array index at x, then increment x

I should be able to write something like

myArray[5 =+ x] = 137; // Write 137 to array index at x, then add five to x

Of course, such an operator does not exist. Is there a reason for this? It seems like a weird asymmetry in C/C++/Java.

preguntado el 08 de enero de 11 a las 23:01

So, basically, you ask why is it allowed only for the special case of ±1? -

Personally, I am in favor of the myArray[x++++++++++++++++++++] = 137; sintaxis. -

@pst Or how about myArray[x.plusPlus(10)] = 137; -

@templatetypedef : I think, this looks better >> myArray[x=+5] = 137; (post addition) ... and the existing one >> myArray[x+=5] = 137; (pre addition).... the idea is, keep x always on the left side! -

debería x=-1 ser analizado como x =- 1 o como x = -1? :) -

7 Respuestas

I'd guess there are several reasons, I think among the more heavily weighted might be:

  • there probably weren't thought to be too many real use cases (it may not have even occurred to some language designers in the early days)
  • pre/post increment mapped directly to machine operations (at least on several machines), so they found their way into the language (update: it turns out that this isn't exactly true, even if it's commonly thought so in computing lore. See below).

Then again, while the idea for pre/post/increment/decrement operators might have been influenced by machine operations, it looks like they weren't put into the language specifically to take advantage of such. Here's what Dennis Ritchie has to say about them:

http://cm.bell-labs.com/cm/cs/who/dmr/chist.html

Thompson went a step further by inventing the ++ and -- operators, which increment or decrement; their prefix or postfix position determines whether the alteration occurs before or after noting the value of the operand. They were not in the earliest versions of B, but appeared along the way. People often guess that they were created to use the auto-increment and auto-decrement address modes provided by the DEC PDP-11 on which C and Unix first became popular. This is historically impossible, since there was no PDP-11 when B was developed. The PDP-7, however, did have a few `auto-increment' memory cells, with the property that an indirect memory reference through them incremented the cell. This feature probably suggested such operators to Thompson; the generalization to make them both prefix and postfix was his own. Indeed, the auto-increment cells were not used directly in implementation of the operators, and a stronger motivation for the innovation was probably his observation that the translation of ++x was smaller than that of x=x+1.

Respondido el 09 de enero de 11 a las 03:01

Mientras y has no side effects:

#define POSTADD(x,y) (((x)+=(y))-(y))

Respondido el 09 de enero de 11 a las 02:01

Or with some side-effect safety in C++: template <typename T, typename U> T postadd( T& x, U increment) { T tmp = x; x = x + increment; return tmp; } But I'd strongly recommend to avoid using something like this (if there's a good reason for using it, I'd like to hear the justification - it might be interesting). - Michael Burr

I'll make an assumption. There're lots of use-cases for ++i/i++ and in many the specific type of increment (pre/post) makes difference. I can't tell how many times I've seen code like while (buf[i++]) {...}. Por otra parte, += is used much less frequently, as it rarely makes sense to shift pointer by 5 elements at once.

So, there's just no common enough application where difference between postfix and prefix version of += would be important.

Respondido el 09 de enero de 11 a las 02:01

I guess it's because it's way too cryptic. Some argue that even ++/-- should be avoided, because they cause confusion and are responsible for most buffer overrun bugs.

Respondido el 09 de enero de 11 a las 02:01

I use postfix ++ (and less often --) only and only in for loops. - Goran Jovic

@Goran: That's great for C, but not so much for C++ (where postfix operations on iterators can be quite expensive). - Ben Voigt

"Some argue that even ++/-- should be avoided, because they cause confusion and are responsible for most buffer overrun bugs.": I don't buy that argument. It's not the ++ or --, it's failure to pay attention to the length of the buffer. += won't help you avoid a buffer overflow if you don't pay attention to the length of the buffer. - Max Lybbert

@Max Lybbert: I think that the arguments tries to state that for (; n > 0; --n) *dst++ = *src++; is not a style one should use. - Stefan

There are a lot of things to avoid, but that doesn't say anything about the merits of ++ y --. My copy of The C Programming Language goes through a lot of effort explaining why while (*src++ = *dest++) ; copies null-terminated strings (and claiming that any C programmer should understand it, even if they don't use that style). The example given works fine if both dst y src son al menos n items long. It fails only when the programmer isn't paying attention to the lengths of the buffers, and switching to += y -= doesn't make the code any better. - Max Lybbert

Because the -- and ++ operators map to inc(rement) and dec(rement) instructions (in addition to adding and subtracting) in the CPU, and these operators are Supuesto to map to the instructions, hence why they exist as separate operators.

Respondido el 09 de enero de 11 a las 03:01

But this is only true for one processor architecture, right? I don't remember seeing this anywhere in MIPS, for example. - templatetypedef

Yeah, it's true for some, the one I know of being x86. - user541686

@templatetypedef: The PDP-11 is just a little bit older than MIPS and C was originally written to work with the PDP-11. Everyone else has pre- and post- increment and decrement operators because C has them. - mu es demasiado corto

Java and C++ have pre- and post- increment and decrement operators because C has them. C has them because C was written, mostly, for the PDP-11 and the PDP-11 had INC y DEC instrucciones.

Back in the day, optimizing compilers didn't exist so if you wanted to use a single cycle increment operator, either you wrote assembler for it or your language needed an explicit operator for it; C, being a portable assembling language, has explicit increment and decrement operators. Also, the performance difference between ++i y i++ rarely matters now but it did matter in 1972.

Keep in mind that C is almost 40 years old.

Respondido el 09 de enero de 11 a las 04:01

However, a startling number of SO/web questions still seem to relate to the "performance" of i++ vs ++i vs i = i + 1 ... :-/ - user166390

If I had to guess, it's common to equate:

x += 5;

...con:

x = x + 5;

And for obvious reasons, it would be nonsensical to write:

x + 5 = x;

I'm not sure how else you would mimic the behavior of 5 =+ x using just the + operator. By the way, hi htiek!

Respondido el 09 de enero de 11 a las 02:01

Clearly it's possible. In the case of x + 5 = x se puede demostrar que 5 = 0 with the subtraction of x from both sides. QED. ;-) - user166390

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.