Code style in C (and C++) loops: postfix and prefix increments - c++

These days I see this very often:
for (int i = 0; i < NUMBER; ++i)
Rather than - as was very much the fashion (?) 20 years ago - this:
for (int i = 0; i < NUMBER; i++)
Is there a reason for this change or is it just fashion?
(There is a similar question about Java here but I don't think the answers get to the heart of the matter)

C and C++
Post-increment involves a temporary that can be avoided by using pre-increment (Post-increment and Pre-increment concept?).
C++
If only integers are involved, the issue is not that critical and the compiler can probably optimize both versions to do essentially the same. However, in C++ basically any object of class type can have a ++ (both post- and pre-) and that can be overloaded to do basically anything. Post-incrementing a big object has a cost and depending on how to operator is implemented the compiler might not be able to optimize both post- and pre-increment to do essentially the same thing. To be on the save side it is prefered to use ++i.
20 years ago
Actually the only thing that changed with respect to this issue is that compiler optimizations got much better over time. I didn't check any old compiler, but I would say that 20 years ago missing compiler optimizations were a much stronger reason to use ++i instead of i++. Maybe what you observed is just style of code getting better.

It's mostly fashion, but also a combination of consistency and misunderstanding.
When iterators came along, and more and more people started realising that ++it could be cheaper than it++, for some more-complex-than-a-pointer iterator it, they started getting into the habit of pre-incrementing everywhere, to save what they perceived to be unnecessary copies in the semantics of a post-increment (the original value would have to be stored temporarily for returning after the increment occurs). They'd then do that for integers too, because why not?
In reality, there's nothing to save. Your compiler is perfectly capable of spotting that the evaluated result is never used here, so ++it and it++ in this context have exactly identical semantics (unless there is some non-idiomatic side effect in the definition of the operator). This is particularly the case for a simple integer i.
It doesn't hurt, of course, and it does eliminate the risk that you've missed some weird angle that does result in an unnecessary copy. It's a good practice. It's just that it hasn't come about out of necessity.

Related

What purpose does the pre-increment operator serve in C? [duplicate]

This question already has answers here:
What are the historical reasons C languages have pre-increments and post-increments?
(6 answers)
Closed 6 years ago.
In C and many of its derivatives, i++ increments i and evaluates to the value of i before it was incremented, and ++i increments i and evaluates to the value of i after it was incremented.
I can see the reasoning for a specific increment operator; many processors at the time had a special increment opcode that was faster than addition and conceptually "increment" is a different idea from "add," in theory having them be written differently might make code more readable.
What I don't understand is the need for the pre-increment operator. Can't any practical use for it be written like this?
#This...
x = i++;
#becomes this:
x = i;
++i;
Is there a historical reason I don't know about, maybe? Were you unable to "throw away" the return values of operators in primordial versions of C?
One reason is that it allowed for the generation of efficient code without having any fancy optimisation phases in compilers, provided that the programmer knew what he (or she) was doing. For example, when copying characters from one buffer to another, you might have:
register char *ptr1;
register char *ptr2;
...
for ( ... ) {
*ptr1++ = *ptr2++; /* post-increment */
}
A compiler that I once worked with (on a proprietary minicomputer) would generate the following register operations for the assignment:
load $r1,*$a1++ // load $r1 from address in $a1 and increment $a1
store $r1,*$a2++ // store $r1 at address in $a2 and increment $a2
I forget the actual opcodes. The compiler contained no optimisation phase yet the code that it generated was very tight providing that you understood the compiler and the machine architecture. It could do this because the hardware architecture had pre-decrement and post-increment addressing modes for both address registers and general registers. There were no pre-increment and post-decrement addressing modes as far as I recall but you could get by without those.
I believe that the DEC minicomputers on which C was originally developed had such addressing modes. The machine that I worked on wasn't made by DEC but the architecture was pretty similar.
An optimisation phase was planned for the compiler. However, it was mostly used by systems programmers and when they saw how good the generated code was, implementation of the optimisation phase was quietly shelved.
The whole rationale for the design of C was to allow the creation of simple and portable compilers that would generate reasonably efficient code with minimal (or no) intermediate code optimisation. For this reason, the increment and decrement operators and also the compound assignment operators played an important role in the generation of compact and efficient code by the early C compilers. They were not just syntactic sugar as suggested by Niklaus Wirth et al.
So you can, for example, do this
While (++i < threshold) [do something];
and this...
While (i++ < threshold) [do something];
or any of a thousand other specific implementations that both use the value and increment it in a single statement and get the expected different results

what's the difference of i++ and ++i in for loop? [duplicate]

Perhaps it doesn't matter to the compiler once it optimizes, but in C/C++, I see most people make a for loop in the form of:
for (i = 0; i < arr.length; i++)
where the incrementing is done with the post fix ++. I get the difference between the two forms. i++ returns the current value of i, but then adds 1 to i on the quiet. ++i first adds 1 to i, and returns the new value (being 1 more than i was).
I would think that i++ takes a little more work, since a previous value needs to be stored in addition to a next value: Push *(&i) to stack (or load to register); increment *(&i). Versus ++i: Increment *(&i); then use *(&i) as needed.
(I get that the "Increment *(&i)" operation may involve a register load, depending on CPU design. In which case, i++ would need either another register or a stack push.)
Anyway, at what point, and why, did i++ become more fashionable?
I'm inclined to believe azheglov: It's a pedagogic thing, and since most of us do C/C++ on a Window or *nix system where the compilers are of high quality, nobody gets hurt.
If you're using a low quality compiler or an interpreted environment, you may need to be sensitive to this. Certainly, if you're doing advanced C++ or device driver or embedded work, hopefully you're well seasoned enough for this to be not a big deal at all. (Do dogs have Buddah-nature? Who really needs to know?)
It doesn't matter which you use. On some extremely obsolete machines, and in certain instances with C++, ++i is more efficient, but modern compilers don't store the result if it's not stored. As to when it became popular to postincriment in for loops, my copy of K&R 2nd edition uses i++ on page 65 (the first for loop I found while flipping through.)
For some reason, i++ became more idiomatic in C, even though it creates a needless copy. (I thought that was through K&R, but I see this debated in other answers.) But I don't think there's a performance difference in C, where it's only used on built-ins, for which the compiler can optimize away the copy operation.
It does make a difference in C++, however, where i might be a user-defined type for which operator++() is overloaded. The compiler might not be able to assert that the copy operation has no visible side-effects and might thus not be able to eliminate it.
As for the reason why, here is what K&R had to say on the subject:
Brian Kernighan
you'll have to ask dennis (and it might be in the HOPL paper). i have a
dim memory that it was related to the post-increment operation in the
pdp-11, though beyond that i don't know, so don't quote me.
in c++ the preferred style for iterators is actually ++i for some subtle
implementation reason.
Dennis Ritchie
No particular reason, it just became fashionable. The code produced
is identical on the PDP-11, just an inc instruction, no autoincrement.
HOPL Paper
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.
For integer types the two forms should be equivalent when you don't use the value of the expression. This is no longer true in the C++ world with more complicated types, but is preserved in the language name.
I suspect that "i++" became more popular in the early days because that's the style used in the original K&R "The C Programming Language" book. You'd have to ask them why they chose that variant.
Because as soon as you start using "++i" people will be confused and curios. They will halt there everyday work and start googling for explanations. 12 minutes later they will enter stack overflow and create a question like this. And voila, your employer just spent yet another $10
Going a little further back than K&R, I looked at its predecessor: Kernighan's C tutorial (~1975). Here the first few while examples use ++n. But each and every for loop uses i++. So to answer your question: Almost right from the beginning i++ became more fashionable.
My theory (why i++ is more fashionable) is that when people learn C (or C++) they eventually learn to code iterations like this:
while( *p++ ) {
...
}
Note that the post-fix form is important here (using the infix form would create a one-off type of bug).
When the time comes to write a for loop where ++i or i++ doesn't really matter, it may feel more natural to use the postfix form.
ADDED: What I wrote above applies to primitive types, really. When coding something with primitive types, you tend to do things quickly and do what comes naturally. That's the important caveat that I need to attach to my theory.
If ++ is an overloaded operator on a C++ class (the possibility Rich K. suggested in the comments) then of course you need to code loops involving such classes with extreme care as opposed to doing simple things that come naturally.
At some level it's idiomatic C code. It's just the way things are usually done. If that's your big performance bottleneck you're likely working on a unique problem.
However, looking at my K&R The C Programming Language, 1st edition, the first instance I find of i in a loop (pp 38) does use ++i rather than i++.
Im my opinion it became more fashionable with the creation of C++ as C++ enables you to call ++ on non-trivial objects.
Ok, I elaborate: If you call i++ and i is a non-trivial object, then storing a copy containing the value of i before the increment will be more expensive than for say a pointer or an integer.
I think my predecessors are right regarding the side effects of choosing postincrement over preincrement.
For it's fashonability, it may be as simple as that you start all three expressions within the for statement the same repetitive way, something the human brain seems to lean towards to.
I would add up to what other people told you that the main rule is: be consistent. Pick one, and do not use the other one unless it is a specific case.
If the loop is too long, you need to reload the value in the cache to increment it before the jump to the begining.
What you don't need with ++i, no cache move.
In C, all operators that result in a variable having a new value besides prefix inc/dec modify the left hand variable (i=2, i+=5, etc). So in situations where ++i and i++ can be interchanged, many people are more comfortable with i++ because the operator is on the right hand side, modifying the left hand variable
Please tell me if that first sentence is incorrect, I'm not an expert with C.

Is ++(a = b); faster than a = b + 1;?

Is it faster to use ++(a = b); instead of a = b + 1;?
For my understanding, the first approach consists of the operations:
move the value of b to a
increment a in memory
while the second approach does:
push b and 1 to the stack
call add
pop the result to a register
move the register to a
Does it actually take less cycles? Or does the compiler (gcc for example) do an optimization so it does not make a difference?
edit: TIL that ++(a=b) is wrong illegal UB, at least in pre-C++11. Nevertheless, I'll discuss this assuming it's either legal or the compiler does what you expect.
Generally speaking, a = b + 1; is faster.
The optimizer will most surely make the same of both. If not, it is more likely to optimize the second version, because it is a very common thing to write, and omtimizers are more likely to recognize common things than weird corner cases.
Why do I say it should be the same after optimization, but the second is faster? Because of the fellow developers. Everyone recognizes a = b + 1; immediately. Noone really has to think about it. The other case is more likely to trigger a reaction in the likes of "wtf is he doing there, and why?". Many people will figure out eventually what you did there. Some will not. Some might even introduce bugs because of it. Few people will find out why you did it and nevertheless stumble each time they have to read that line. Everyone will lose time wondering while reading that line. That's why the other is faster.
Caveat: all this is written silently assuming that you are talking of builtin types, like ints or pointers. Your interpretation of what the two do supports that. If we're talking of UDTs, the two lines are not even guaranteed to do the same. It then depends completely on how operator=, operator++ and operator+ and maybe the conversion from int are implemented. Nevertheless, if the implementations make you conside to write ++(a=b), they are most likely bad implementations and should be improved rather than hacked around.
tl;dr: if I'd catch you doing ++(a=b) in any codebase I work on, we'd have to have a serious talk ;-)
There is no simple answer to this question. The question has been flagged with C++ so we have no way of knowing what this code is actually doing without knowing the precise type of all the operands. Also, the context within which the code appears will make a difference to the way the optimiser generates code - the compiler could alias the variables and move the increment into instructions further down the program, for example, into effective address calculations for the two variables.
But the real question is, why do you care? As Arne said above, readability is far more important and you've not posted a scenario whereby any difference would have a measurable effect.
Only worry about it if it is actually causing a problem.
With optimizations on, they generate exactly the same code for me so they will perform exactly the same. This shouldn't be a surprise as the effects of both statements are exactly the same.
++(a = b); is undefined behaviour because there are two unsequenced modifications to a.
Although the value computation of a in a = b is sequenced before the modification of a due ++, the side-effect of a = b (storage to a) is unsequenced relative to the side-effect of ++ (again, storage to a).

Programming Myth? Pre vs. post increment and decrement speed [duplicate]

Is there a performance difference between i++ and ++i if the resulting value is not used?
Executive summary: No.
i++ could potentially be slower than ++i, since the old value of i
might need to be saved for later use, but in practice all modern
compilers will optimize this away.
We can demonstrate this by looking at the code for this function,
both with ++i and i++.
$ cat i++.c
extern void g(int i);
void f()
{
int i;
for (i = 0; i < 100; i++)
g(i);
}
The files are the same, except for ++i and i++:
$ diff i++.c ++i.c
6c6
< for (i = 0; i < 100; i++)
---
> for (i = 0; i < 100; ++i)
We'll compile them, and also get the generated assembler:
$ gcc -c i++.c ++i.c
$ gcc -S i++.c ++i.c
And we can see that both the generated object and assembler files are the same.
$ md5 i++.s ++i.s
MD5 (i++.s) = 90f620dda862cd0205cd5db1f2c8c06e
MD5 (++i.s) = 90f620dda862cd0205cd5db1f2c8c06e
$ md5 *.o
MD5 (++i.o) = dd3ef1408d3a9e4287facccec53f7d22
MD5 (i++.o) = dd3ef1408d3a9e4287facccec53f7d22
From Efficiency versus intent by Andrew Koenig :
First, it is far from obvious that ++i is more efficient than i++, at least where integer variables are concerned.
And :
So the question one should be asking is not which of these two operations is faster, it is which of these two operations expresses more accurately what you are trying to accomplish. I submit that if you are not using the value of the expression, there is never a reason to use i++ instead of ++i, because there is never a reason to copy the value of a variable, increment the variable, and then throw the copy away.
So, if the resulting value is not used, I would use ++i. But not because it is more efficient: because it correctly states my intent.
A better answer is that ++i will sometimes be faster but never slower.
Everyone seems to be assuming that i is a regular built-in type such as int. In this case there will be no measurable difference.
However if i is complex type then you may well find a measurable difference. For i++ you must make a copy of your class before incrementing it. Depending on what's involved in a copy it could indeed be slower since with ++i you can just return the final value.
Foo Foo::operator++()
{
Foo oldFoo = *this; // copy existing value - could be slow
// yadda yadda, do increment
return oldFoo;
}
Another difference is that with ++i you have the option of returning a reference instead of a value. Again, depending on what's involved in making a copy of your object this could be slower.
A real-world example of where this can occur would be the use of iterators. Copying an iterator is unlikely to be a bottle-neck in your application, but it's still good practice to get into the habit of using ++i instead of i++ where the outcome is not affected.
Short answer:
There is never any difference between i++ and ++i in terms of speed. A good compiler should not generate different code in the two cases.
Long answer:
What every other answer fails to mention is that the difference between ++i versus i++ only makes sense within the expression it is found.
In the case of for(i=0; i<n; i++), the i++ is alone in its own expression: there is a sequence point before the i++ and there is one after it. Thus the only machine code generated is "increase i by 1" and it is well-defined how this is sequenced in relation to the rest of the program. So if you would change it to prefix ++, it wouldn't matter in the slightest, you would still just get the machine code "increase i by 1".
The differences between ++i and i++ only matters in expressions such as array[i++] = x; versus array[++i] = x;. Some may argue and say that the postfix will be slower in such operations because the register where i resides has to be reloaded later. But then note that the compiler is free to order your instructions in any way it pleases, as long as it doesn't "break the behavior of the abstract machine" as the C standard calls it.
So while you may assume that array[i++] = x; gets translated to machine code as:
Store value of i in register A.
Store address of array in register B.
Add A and B, store results in A.
At this new address represented by A, store the value of x.
Store value of i in register A // inefficient because extra instruction here, we already did this once.
Increment register A.
Store register A in i.
the compiler might as well produce the code more efficiently, such as:
Store value of i in register A.
Store address of array in register B.
Add A and B, store results in B.
Increment register A.
Store register A in i.
... // rest of the code.
Just because you as a C programmer is trained to think that the postfix ++ happens at the end, the machine code doesn't have to be ordered in that way.
So there is no difference between prefix and postfix ++ in C. Now what you as a C programmer should be vary of, is people who inconsistently use prefix in some cases and postfix in other cases, without any rationale why. This suggests that they are uncertain about how C works or that they have incorrect knowledge of the language. This is always a bad sign, it does in turn suggest that they are making other questionable decisions in their program, based on superstition or "religious dogmas".
"Prefix ++ is always faster" is indeed one such false dogma that is common among would-be C programmers.
Taking a leaf from Scott Meyers, More Effective c++ Item 6: Distinguish between prefix and postfix forms of increment and decrement operations.
The prefix version is always preferred over the postfix in regards to objects, especially in regards to iterators.
The reason for this if you look at the call pattern of the operators.
// Prefix
Integer& Integer::operator++()
{
*this += 1;
return *this;
}
// Postfix
const Integer Integer::operator++(int)
{
Integer oldValue = *this;
++(*this);
return oldValue;
}
Looking at this example it is easy to see how the prefix operator will always be more efficient than the postfix. Because of the need for a temporary object in the use of the postfix.
This is why when you see examples using iterators they always use the prefix version.
But as you point out for int's there is effectively no difference because of compiler optimisation that can take place.
Here's an additional observation if you're worried about micro optimisation. Decrementing loops can 'possibly' be more efficient than incrementing loops (depending on instruction set architecture e.g. ARM), given:
for (i = 0; i < 100; i++)
On each loop you you will have one instruction each for:
Adding 1 to i.
Compare whether i is less than a 100.
A conditional branch if i is less than a 100.
Whereas a decrementing loop:
for (i = 100; i != 0; i--)
The loop will have an instruction for each of:
Decrement i, setting the CPU register status flag.
A conditional branch depending on CPU register status (Z==0).
Of course this works only when decrementing to zero!
Remembered from the ARM System Developer's Guide.
First of all: The difference between i++ and ++i is neglegible in C.
To the details.
1. The well known C++ issue: ++i is faster
In C++, ++i is more efficient iff i is some kind of an object with an overloaded increment operator.
Why?
In ++i, the object is first incremented, and can subsequently passed as a const reference to any other function. This is not possible if the expression is foo(i++) because now the increment needs to be done before foo() is called, but the old value needs to be passed to foo(). Consequently, the compiler is forced to make a copy of i before it executes the increment operator on the original. The additional constructor/destructor calls are the bad part.
As noted above, this does not apply to fundamental types.
2. The little known fact: i++ may be faster
If no constructor/destructor needs to be called, which is always the case in C, ++i and i++ should be equally fast, right? No. They are virtually equally fast, but there may be small differences, which most other answerers got the wrong way around.
How can i++ be faster?
The point is data dependencies. If the value needs to be loaded from memory, two subsequent operations need to be done with it, incrementing it, and using it. With ++i, the incrementation needs to be done before the value can be used. With i++, the use does not depend on the increment, and the CPU may perform the use operation in parallel to the increment operation. The difference is at most one CPU cycle, so it is really neglegible, but it is there. And it is the other way round then many would expect.
Please don't let the question of "which one is faster" be the deciding factor of which to use. Chances are you're never going to care that much, and besides, programmer reading time is far more expensive than machine time.
Use whichever makes most sense to the human reading the code.
#Mark
Even though the compiler is allowed to optimize away the (stack based) temporary copy of the variable and gcc (in recent versions) is doing so,
doesn't mean all compilers will always do so.
I just tested it with the compilers we use in our current project and 3 out of 4 do not optimize it.
Never assume the compiler gets it right, especially if the possibly faster, but never slower code is as easy to read.
If you don't have a really stupid implementation of one of the operators in your code:
Alwas prefer ++i over i++.
I have been reading through most of the answers here and many of the comments, and I didn't see any reference to the one instance that I could think of where i++ is more efficient than ++i (and perhaps surprisingly --i was more efficient than i--). That is for C compilers for the DEC PDP-11!
The PDP-11 had assembly instructions for pre-decrement of a register and post-increment, but not the other way around. The instructions allowed any "general-purpose" register to be used as a stack pointer. So if you used something like *(i++) it could be compiled into a single assembly instruction, while *(++i) could not.
This is obviously a very esoteric example, but it does provide the exception where post-increment is more efficient(or I should say was, since there isn't much demand for PDP-11 C code these days).
In C, the compiler can generally optimize them to be the same if the result is unused.
However, in C++ if using other types that provide their own ++ operators, the prefix version is likely to be faster than the postfix version. So, if you don't need the postfix semantics, it is better to use the prefix operator.
I can think of a situation where postfix is slower than prefix increment:
Imagine a processor with register A is used as accumulator and it's the only register used in many instructions (some small microcontrollers are actually like this).
Now imagine the following program and their translation into a hypothetical assembly:
Prefix increment:
a = ++b + c;
; increment b
LD A, [&b]
INC A
ST A, [&b]
; add with c
ADD A, [&c]
; store in a
ST A, [&a]
Postfix increment:
a = b++ + c;
; load b
LD A, [&b]
; add with c
ADD A, [&c]
; store in a
ST A, [&a]
; increment b
LD A, [&b]
INC A
ST A, [&b]
Note how the value of b was forced to be reloaded. With prefix increment, the compiler can just increment the value and go ahead with using it, possibly avoid reloading it since the desired value is already in the register after the increment. However, with postfix increment, the compiler has to deal with two values, one the old and one the incremented value which as I show above results in one more memory access.
Of course, if the value of the increment is not used, such as a single i++; statement, the compiler can (and does) simply generate an increment instruction regardless of postfix or prefix usage.
As a side note, I'd like to mention that an expression in which there is a b++ cannot simply be converted to one with ++b without any additional effort (for example by adding a - 1). So comparing the two if they are part of some expression is not really valid. Often, where you use b++ inside an expression you cannot use ++b, so even if ++b were potentially more efficient, it would simply be wrong. Exception is of course if the expression is begging for it (for example a = b++ + 1; which can be changed to a = ++b;).
I always prefer pre-increment, however ...
I wanted to point out that even in the case of calling the operator++ function, the compiler will be able to optimize away the temporary if the function gets inlined. Since the operator++ is usually short and often implemented in the header, it is likely to get inlined.
So, for practical purposes, there likely isn't much of a difference between the performance of the two forms. However, I always prefer pre-increment since it seems better to directly express what I"m trying to say, rather than relying on the optimizer to figure it out.
Also, giving the optmizer less to do likely means the compiler runs faster.
My C is a little rusty, so I apologize in advance. Speedwise, I can understand the results. But, I am confused as to how both files came out to the same MD5 hash. Maybe a for loop runs the same, but wouldn't the following 2 lines of code generate different assembly?
myArray[i++] = "hello";
vs
myArray[++i] = "hello";
The first one writes the value to the array, then increments i. The second increments i then writes to the array. I'm no assembly expert, but I just don't see how the same executable would be generated by these 2 different lines of code.
Just my two cents.

increment operator more purpose? [duplicate]

This question already has answers here:
rate ++a,a++,a=a+1 and a+=1 in terms of execution efficiency in C.Assume gcc to be the compiler [duplicate]
(10 answers)
Which is faster? ++, += or x + 1?
(5 answers)
Closed 9 years ago.
I was wondering if the increment and decrement operators ( ++ -- ) have more purpose to it than its plain use to make the code more simple
maybe:
i++;
is more efficient than:
i = i + 1;
?
In many ways, the main purpose of the operators is backwards
compatibility. When C++ was being designed, the general rule
was to do what C did, at least for non-class types; if C hadn't
had ++ and --, I doubt C++ would have them.
Which, of course, begs the question. It's inconceivable that
they would generate different code in a modern compiler, and
it's fairly inconceivable that the committee would introduce
them for optimization reasons (although you never
know—move semantics were introduced mainly for
optimization reasons). But back in the mid-1970s, in the
formative years of C? It was generally believed, at the time,
that they were introduced because they corresponded to machine
instructions on the PDP-11. On the other hand, they were
already present in B. C acquired them from B. And B was an
interpreted language, so there was no issue of them
corresponding to machine instructions. My own suspicion, which
applies to many of the operators (&, rather than and, etc.)
is that they were introduced because development at the time was
largely on teletypes (tty's), and every character you output to
a teletype made a lot of unpleasant noise. So the less
characters you needed, the better.
As to the choice between ++ i;, i += 1; and i = i + 1;:
there is a decided advantage to not having to repeat the i
(which can, of course, be a more or less complex expression), so
you want at least i += 1;. Python stops there, if for no
other reason than it treats assignment as a statement, rather
than as the side effect of an arbitrary expression. With over
30 years of programming in C and C++ under my belt, I still feel
that ++ i is missing when programming in Python, even though I
pretty much restrict myself in C++ to treating assignment as a
statement (and don't embed ++ i in more complicated
expressions).
Performance depends on the type of i.
If it's a built-in type, then optimizers will "notice" that your two statements are the same, and emit the same code for both.
Since you used post-increment (and ignoring your semi-colons), the two expressions have different values even when i is a built-in type. The value of i++ is the old value, the value of i = i + 1 is the new value. So, if you write:
j = i++;
k = (i = i + 1);
then the two are now different, and the same code will not be emitted for both.
Since the post-condition of post-increment is the same as pre-increment, you could well say that the primary purpose of the post-increment operator is that it evaluates to a different value. Regardless of performance, it makes the language more expressive.
If i has class type with overloaded operators then it might not be so simple. In theory the two might not even have the same result, but assuming "sensible" operators i + 1 returns a new instance of the class, which is then move-assigned (in C++11 if the type has a move assignment operator) or copy-assigned (in C++03) to i. There's no guarantee that the optimizer can make this as efficient as what operator++ does, especially if the operator overload definitions are off in another translation unit.
Some types have operator++ but not operator+, for example std::list<T>::iterator. That's not the reason ++ exists, though, since it existed in C and C has no types with ++ but not +. It is a way that C++ has taken advantage of it existing.
The two examples you gave will almost certainly compile to exactly the same machine code. Compilers are very smart. Understand that a compiler rarely executes the code you actually wrote. It will twist it and mould it to improve performance. Any modern compiler will know that i++; and i = i + 1; are identical (for an arithmetic type) and generate the same output.
However, there is a good reason to have both, other than just code readability. Conceptually, incrementing a value many times and adding to a value are different operations - they are only the same here because you are adding 1. An addition, such as x + 3, is a single operation, whereas doing ++++++x represents three individual operations with the same effect. Of course, a smart compiler will also know that for an object of arithmetic type, x, it can do N increments in constant time just by doing x + N.
However, the compiler can't make this assumption if x is of class type with an overloaded operator+ and operator++. These two operators may do entirely different things. In addition, implementing an operator+ as a non-constant time operation would give the wrong impression.
The importance of having both becomes clear when we're dealing with iterators. Only Random Access Iterators support addition and subtraction. For example, a standard raw pointer is a random access iterator because you can do ptr + 5 and get a pointer to the 5th object along. However, all other types of iterators (bidirectional, forward, input) do not support this - you can only increment them (and decrement a bidirectional iterator). To get to the 5th element along with a bidirectional iterator, you need to do ++ five times. That's because an addition represents a constant time operation but many iterators simply cannot traverse in constant time. Forcing multiple increments shows that it's not a constant time operation.
Both would produce same machine instruction(s) in optimized code by a decent compiler.
If the compiler sees i++ is more efficient,then it will convert i=i+1 to i++, or vice-versa. The result will be same no matter what you write.
I prefer ++i . I never write i=i+1.
No, it is simply to make typing simple, and to get simpler looking syntax.
When they are both compiled, they are reduced to the same compiled code, and run at the same speed.
The ++ or -- operator allows it to be combined into other statements rather than i=i+1. For e.g. while (i++ < 10) allows a while loop check and an increment to be done after it. It's not possible to do that with i=i+1.
The ++ or -- operator can be overloaded in other classes to have other meanings or to do increments and decrements with additional actions. Please see this page for more info.
Try to replace ++i or i++ in some more complicated expression. You're going to have difficulties with the preincrement/postincrement feature. You're going to need to split the expression into multiple ones. It's like ternary operator. It is equivalent, the compiler may perform some optimizations regardless on the way you enter the code, but ternary operator and preincrement/postincrement syntax just save you space and readability of the code.
They both are not exactly same , though functionally they are same, there is a difference in precedencei++ has more precedence(more priority) than i=i+1
The difference between i++ and i = i + 1 is that the first expression only evaluates i once and the second evaluates it twice. Consider:
int& f() {
static int value = 0;
std::cout << "f() called\n";
return value;
}
f()++; // writes the message once
f() = f() + 1; // writes the message twice
And if f() returns different references on different calls, the two expressions have vastly different effects. Not that this is good design, of course...