454,440 Members | 1,436 Online
Need help? Post your question and get tips & solutions from a community of 454,440 IT Pros & Developers. It's quick & easy.

i++, ++i, i+=1 and i = i+1;

 P: n/a Hello, let say we have; 1) i++; /* use i and increment by one */ 2) ++i; /* increment i by one and use it */ 3) i += 1; 4) i = i+1; result (for value of i) of all 4 will be same; could anyone tell differences among them from any perspectives? I heard we'd better use 2) over 1). And 1) is faster than 3) or 4). Thanks in advance, Dec 19 '06 #1
20 Replies

 P: n/a jim said: Hello, let say we have; 1) i++; /* use i and increment by one */ 2) ++i; /* increment i by one and use it */ 3) i += 1; 4) i = i+1; result (for value of i) of all 4 will be same; could anyone tell differences among them from any perspectives? I heard we'd better use 2) over 1). And 1) is faster than 3) or 4). Use the one you think most clearly conveys your intent. Premature optimisation is the root of all evil, as Donald Knuth rightly said. -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Dec 19 '06 #2

 P: n/a 2006-12-19 , Richard Heathfield wrote: jim said: >Hello,let say we have;1) i++; /* use i and increment by one */2) ++i; /* increment i by one and use it */3) i += 1;4) i = i+1;result (for value of i) of all 4 will be same; could anyone telldifferences among them from any perspectives?I heard we'd better use 2) over 1). And 1) is faster than 3) or 4). Use the one you think most clearly conveys your intent. Premature optimisation is the root of all evil, as Donald Knuth rightly said. Note that 1 does have a meaning slightly different than 2 3 or 4, if used in an expression. Any compiler worth anything will compile all four [in a statement by themselves, and 2 3 4 anywhere in an expression] to exactly the same thing - so, yeah, use whichever one is most readable. And "i+++1" instead of "++i" is just silly. Dec 19 '06 #3

 P: n/a "jim"

 P: n/a jim wrote: Hello, let say we have; 1) i++; /* use i and increment by one */ 2) ++i; /* increment i by one and use it */ 3) i += 1; 4) i = i+1; result (for value of i) of all 4 will be same; Better to say the side effect will be the same, the result of the expression is clearly different for the first case. could anyone tell differences among them from any perspectives? As stand alone statements, there's none. I heard we'd better use 2) over 1). And 1) is faster than 3) or 4). You most likely heard that in a C++ context with particular reference to i being an iterator. Note that C and C++ are different languages with different paradigms and you'll only confuse yourself if you mix the two. [From the question I'm assuming you're a relative newbie.] So if you're currently learning C++, I suggest you hop over to a C++ group. Note that this question is almost certainly a FAQ though. If you're currently learning C but have been reading C++ material in the belief that it's similar, DON'T! -- Peter Dec 19 '06 #5

 P: n/a Random832 wrote: > 2006-12-19 , Richard Heathfield wrote: jim said: Hello, let say we have; 1) i++; /* use i and increment by one */ 2) ++i; /* increment i by one and use it */ 3) i += 1; 4) i = i+1; result (for value of i) of all 4 will be same; could anyone tell differences among them from any perspectives? I heard we'd better use 2) over 1). And 1) is faster than 3) or 4). Use the one you think most clearly conveys your intent. Premature optimisation is the root of all evil, as Donald Knuth rightly said. Note that 1 does have a meaning slightly different than 2 3 or 4, if used in an expression. 4 can have a different meaning from the other three if i is a macro with side effects. -- pete Dec 19 '06 #6

 P: n/a jim skrev: let say we have; 1) i++; /* use i and increment by one */ 2) ++i; /* increment i by one and use it */ 3) i += 1; 4) i = i+1; result (for value of i) of all 4 will be same; could anyone tell differences among them from any perspectives? I heard we'd better use 2) over 1). And 1) is faster than 3) or 4). As Peter mentioned, you most likely heard that in a C++ context where the increment operation is being overloaded. Try to implement the following functions to get a feeling for the difference between 1 and 2: /* Increment the integer pointed at and return the new value. */ int preinc(int *p); /* Increment the integer pointed at and return the old value. */ int postinc(int *p); August Dec 19 '06 #7

 P: n/a Richard Heathfield Hello,let say we have;1) i++; /* use i and increment by one */2) ++i; /* increment i by one and use it */3) i += 1;4) i = i+1;result (for value of i) of all 4 will be same; could anyone telldifferences among them from any perspectives?I heard we'd better use 2) over 1). And 1) is faster than 3) or 4). Use the one you think most clearly conveys your intent. Premature optimisation is the root of all evil, as Donald Knuth rightly said. http://en.wikipedia.org/wiki/Optimiz...mputer_science) Third paragraph. I think the credit must go where it's due. -- vale Dec 20 '06 #8

 P: n/a jim wrote: Hello, let say we have; 1) i++; /* use i and increment by one */ 2) ++i; /* increment i by one and use it */ 3) i += 1; 4) i = i+1; result (for value of i) of all 4 will be same; could anyone tell differences among them from any perspectives? In isolation there is no difference between any of them. On the other hand, if you use any of them as the component of an expression, then the first one can be different. int i, j; i = 2; j = i++; /* j will become 2, i will become 3 */ i = 2; j = ++i; /* j will become 3, i will become 3 */ i = 2; j = (i += 1); /* j will become 3, i will become 3 */ i = 2; j = (i = i + 1); /* j will become 3, i will become 3 */ There are more implications for what all this means for C++ and its operator overloading feature, however that's another suject entirely. There are probably some implications depending on if i is declared volatile and sig_atomic_t as well, but I'm too lazy to work them all out. I heard we'd better use 2) over 1). And 1) is faster than 3) or 4). Its not *better* to use any of them. There is a subtle difference in them so you should use one that is appropriate to your purpose. C abstracts them all to nearly the same thing at compile time, so there is no reason for their to be any speed difference in any of them (matters are slightly different for C++ operator overloading.) -- Paul Hsieh http://www.pobox.com/~qed/ http://bstring.sf.net/ Dec 20 '06 #9

 P: n/a malc said: Richard Heathfield jim said: >>Hello,let say we have;1) i++; /* use i and increment by one */2) ++i; /* increment i by one and use it */3) i += 1;4) i = i+1;result (for value of i) of all 4 will be same; could anyone telldifferences among them from any perspectives?I heard we'd better use 2) over 1). And 1) is faster than 3) or 4). Use the one you think most clearly conveys your intent. Prematureoptimisation is the root of all evil, as Donald Knuth rightly said. http://en.wikipedia.org/wiki/Optimiz...mputer_science) Third paragraph. I think the credit must go where it's due. Hmmm. What makes you think the Wikipedia article is correct? After all, if you look up their C stuff, you'll find that they confuse arguments and parameters at least twice, claim that * is a type qualifier, and assume that all platforms use ASCII. We all know that *anyone* can edit Wikipedia, regardless of their level of knowledge of the subject matter, so why treat the Wiki like some kind of oracle? It's only as good as the last person to edit it. If that was someone who happens to know his or her stuff, you get good information. And if it wasn't, you get bad information. So the question a Wiki reader has to ask himself is: "do I feel lucky?" -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Dec 20 '06 #10

 P: n/a "jim"

 P: n/a "jim"

 P: n/a Richard Heathfield Richard Heathfield >Use the one you think most clearly conveys your intent. Prematureoptimisation is the root of all evil, as Donald Knuth rightly said. http://en.wikipedia.org/wiki/Optimiz...mputer_science)Third paragraph. I think the credit must go where it's due. Hmmm. What makes you think the Wikipedia article is correct? After all, if you look up their C stuff, you'll find that they confuse arguments and parameters at least twice, claim that * is a type qualifier, and assume that all platforms use ASCII. Well, i knew that i have seen discussions on the subject in the past, decided to check with wikipedia and there it was. Furthermore: http://www.google.com/search?q=prema...ations%20hoare yields a lot of hits. All that said, cursory look on the paper where this quote is taken from (and out of context if i might add) does not suggest that Knuth is quoting Hoare. Structured Programming with go to Statements DONALD E. KNUTH Stanford University, Stanford, California 94305 page 268 We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. The first part of the quote makes the rest of it a lot less of a sweeping generalization. After spending some time searching the web i have no definitive proof that Knuth was quoting Hoare, so sorry about that. Then again taking less than a half of a sentence and using that as an appeal to authority is not a right thing to do. > We all know that *anyone* can edit Wikipedia, regardless of their level of knowledge of the subject matter, so why treat the Wiki like some kind of oracle? It's only as good as the last person to edit it. If that was someone who happens to know his or her stuff, you get good information. And if it wasn't, you get bad information. So the question a Wiki reader has to ask himself is: "do I feel lucky?" Perhaps. -- vale Dec 20 '06 #13

 P: n/a malc said: > Then again taking less than a half of a sentence and using that as an appeal to authority is not a right thing to do. I suppose you could view it in that light, but I was simply using Knuth's words because they conveyed, pithily and effectively, a point that I myself wanted to make, and of course I ascribed them to the man whom I believed (and believe) to be their author because, well, one does, doesn't one? -- Richard Heathfield "Usenet is a strange place" - dmr 29/7/1999 http://www.cpax.org.uk email: rjh at the above domain, - www. Dec 20 '06 #14

 P: n/a malc

 P: n/a Ben Pfaff an appeal to authority is not a right thing to do. I agree. Heh, clever. -- vale Dec 20 '06 #16

 P: n/a kr*****@kalleanka.se wrote: "jim"

 P: n/a J. J. Farrell wrote: > kr*****@kalleanka.se wrote: "jim" 1) i++; /* use i and increment by one */ 2) ++i; /* increment i by one and use it */ 3) i += 1; 4) i = i+1; I was told that in case 3) "i" is accessed once and modified once; in case 4) "i" is accessed twice and modified once. I recommend you stop listening to whoever told you that. I disagree. Someone else could hopefully say if it is true and what it means in reality. It may be true, It is true. They should all compile to the same code sequence, which increments i using whatever sequence of operations is most efficient. That all depends on whether or not (i) is an expression with side effects. /* BEGIN new.c ouput */ After: array[0] = 0; array[1] = 7; counter = 0; ++i; i is 7 array[0] is 1 array[1] is 7 After: array[0] = 0; array[1] = 7; counter = 0; i = i + 1; i is 0 array[0] is 0 array[1] is 1 /* END new.c ouput */ /* BEGIN new.c */ #include #define i (*side_effects(array)) static unsigned counter; int *side_effects(int *array); int main(void) { int array[2]; puts("/* BEGIN new.c ouput */\n"); array[0] = 0; array[1] = 7; counter = 0; ++i; printf("After: array[0] = 0;" " array[1] = 7; counter = 0; ++i;\n\n"); printf("i is %d\n", i); printf("array[0] is %d\n", array[0]); printf("array[1] is %d\n\n", array[1]); array[0] = 0; array[1] = 7; counter = 0; i = i + 1; printf("After: array[0] = 0;" " array[1] = 7; counter = 0; i = i + 1;\n\n"); printf("i is %d\n", i); printf("array[0] is %d\n", array[0]); printf("array[1] is %d\n", array[1]); puts("\n/* END new.c ouput */"); return 0; } int *side_effects(int *array) { return array + counter++ % 2; } /* END new.c */ -- pete Dec 21 '06 #18

 P: n/a pete wrote: J. J. Farrell wrote: kr*****@kalleanka.se wrote: "jim"

 P: n/a J. J. Farrell wrote: > pete wrote: J. J. Farrell wrote: > kr*****@kalleanka.se wrote: "jim" 1) i++; /* use i and increment by one */ 2) ++i; /* increment i by one and use it */ 3) i += 1; 4) i = i+1; I was told that in case 3) "i" is accessed once and modified once; in case 4) "i" is accessed twice and modified once. > I recommend you stop listening to whoever told you that. I disagree. Someone else could hopefully say if it is true and what it means in reality. > It may be true, It is true. It may or may not be true; the "as if" rule says so. With anything that deserves the name of "C compiler" in the case that the OP was asking about, it is not true. They should all compile to the same code sequence, which increments i using whatever sequence of operations is most efficient. That all depends on whether or not (i) is an expression with side effects. Indeed, though it's clear from the OP's posting that he was asking about the simple case. It's clear from "I was told that in case 3) "i" is accessed once and modified once; in case 4) "i" is accessed twice and modified once." that what he was being told, was taking the non simple case into account. /* BEGIN new.c ouput */ After: array[0] = 0; array[1] = 7; counter = 0; ++i; i is 7 array[0] is 1 array[1] is 7 After: array[0] = 0; array[1] = 7; counter = 0; i = i + 1; i is 0 array[0] is 0 array[1] is 1 /* END new.c ouput */ In his posting, the OP defined that the end value of i is identical in all four cases, so your example is not relevant to the question in hand. In the example I that gave the value of i was 1, prior to ++i, and the value of i was 1, prior to i = i + 1. -- pete Dec 21 '06 #20

 P: n/a pete wrote: > J. J. Farrell wrote: pete wrote: J. J. Farrell wrote: kr*****@kalleanka.se wrote: "jim" I was told that in case 3) "i" is accessed once and modified once; in case 4) "i" is accessed twice and modified once. I recommend you stop listening to whoever told you that. > I disagree. > Someone else could hopefully say if it is true and what it means in reality. It may be true, > It is true. It may or may not be true; the "as if" rule says so. With anything that deserves the name of "C compiler" in the case that the OP was asking about, it is not true. They should all compile to the same code sequence, which increments i using whatever sequence of operations is most efficient. > That all depends on whether or not (i) is an expression with side effects. Indeed, though it's clear from the OP's posting that he was asking about the simple case. It's clear from "I was told that in case 3) "i" is accessed once and modified once; in case 4) "i" is accessed twice and modified once." that what he was being told, was taking the non simple case into account. /* BEGIN new.c ouput */ > After: array[0] = 0; array[1] = 7; counter = 0; ++i; > i is 7 array[0] is 1 array[1] is 7 > After: array[0] = 0; array[1] = 7; counter = 0; i = i + 1; > i is 0 array[0] is 0 array[1] is 1 > /* END new.c ouput */ In his posting, the OP defined that the end value of i is identical in all four cases, so your example is not relevant to the question in hand. In the example I that gave the value of i was 1, prior to ++i, and the value of i was 1, prior to i = i + 1. I meant to say that the value of i was 0, prior to the assignment operation. Anyway, the comment about the difference bewteen case 3) and case 4), was about the difference in semantics between simple assignment and compound assignment, and was very nearly a quote from the standard. N869 6.5.16.2 Compound assignment Semantics [#3] A compound assignment of the form E1 op= E2 differs from the simple assignment expression E1 = E1 op (E2) only in that the lvalue E1 is evaluated only once. -- pete Dec 21 '06 #21