In my screencast of UIViewController TDD, I used an example of incrementing a counter and couldn't help but give a slight aside: "We'll increment it… ++count, instead of count++, please."
<rant>
I blame Apple for propagating poor incrementing style. Programming with Objective-C starts with the statement, "[Objective-C is] a superset of the C programming language." But every example they give of incrementing a value uses someInteger++, ignoring the fact that C has two different increment operators!
- Post-increment: count++
- Pre-increment: ++count
The Wikipedia article Increment and decrement operators gives clear examples of the difference.
What performance impact will it make? None. The extra code for post-increment semantics is probably optimized away by today's compilers. Even if it's not, it'll still have almost no impact. So what does it matter?
It matters to the reader. It matters because it shows a lack of familiarity with the language's operators, which doesn't fill me with confidence in your code. It matters because Objective-C Is Still C (Not Java!)
Say what you mean, rather than relying on side-effects.
</rant>
Question: Do language subtleties really matter? Leave a comment below.
I’ve known the difference between pre- and post-increment since I started learning C 15 years ago, and I regularly use post-increment in standalone statements. I think it looks cleaner (besides, the language is called C++, not ++C :)
If I’m assigning the result, then obviously I use whichever of the operators that is required.
So how does using post-increment indicate a lack of familiarity with the operators?
Nick, since you know the difference… why would you use post-increment (implying creation of a temporary) when you mean pre-increment? Because it “looks cleaner,” or is there more?
I don’t think it makes a squat of difference performance-wise in C and its derivatives like Objective C, but in C++ and its ilk post-increment and pre-increment are implemented as class operators. Pre-increments tend to be faster due to optimizations possible in return-by-reference values, whereas for post-increments a copy has to be made to be returned.
I guess my C++ background is leaking through…
In my opinion both decrement and increment are redundant inside modern languages, they exists here due to historical reasons: increment and decrement are translated into cheaper processor instructions. But nowadays it not needed anymore. You have shorthand operator += . And this is enough.
someInteger +=1;
is much better than any
someInteger++ or ++someInteger.
Shorthand operators are universal, they exists for many of binary operation, not for adding and subtract.
So stop using both of them. Use the force of semantic)
I have to second Alexey’s reply — I usually use
var += 1;
The use of ++ and — operators, while obviously more compact, break the rule that a variable only changes value within a statement if it’s an lvalue. Writingx = y++;
means that *two* variables take new values within a single statement — I don’t like it.You can also write this:
myVar = myVar++;
Care to predict what the result of that statement is?
Ha ha! Yes, I avoid increment/decrement in assignment.
Ah the memories of doing low level memory-mapped I/O on the Apple ][ and 680xx Macintoshes, where you might strobe an I/O line like this:
byte *ioPort = someAddress;
*ioPort |= 0x01;
*ioPort &= 0xfe;
But I’ve seen abortions like this:
byte *ioPort = someAddress;
*ioPort -= ++*ioPort;
Assuming var is 0 initially, the answers are:
var = 1
x = 0, y = 1
This is where the difference between pre and post matter. If you had written ++y the variable would have been incremented BEFORE the operation (leading to x = 1 and y = 1) which in this case is an assignment, however, since you use post it is incremented AFTER the operation.
myVar = 1
The last one is a bit odd, because what should happen if the compiler does not catch this is that myVar will be set to myVar and THEN it will be incremented, causing an extra assignment that does nothing.
In many cases it does not matter much, however, if you write very compact code where you execute a lot in a small amount of space it can be crucial. For example if we have a variable int i = 0 and add a loop while( printf( “Enter digit: \n” ), scanf(%d, &array[i++]) > 0 ); In this case, if you use ++i instead of i++ it will start adding items to your array at index 1 instead of index 0 which obviously can cause some nasty errors later on in your code if you do not constantly account for this.
Interesting argument, Alexey. You’re right, these operators were built on C really being high-level assembly language. I assume that +=1 is optimized for integers… and it works fine for non-integers.
I also prefer using
+=
and its ilk:* It’s part of a fuller family – there’s also
*=
,/=
, and%=
. Whilex//
would have the side-effect of dividingx
by one, it would be completely by accident!* There’s at least the visual hint of an assignment operator in there
* More generalizable – If for some reason you find you need to skip up by two instead of one, ‘x+=1’ changes to ‘x+=2’ (or ‘x+=skipSize’) easily.
I’ll admit to using
++
out of habit, but I try not to (both pre- and post-)And as for my students… I let them know these things exist, in case I lapse in the name of conserving chalkboard space, but I but discourage using any shortcuts until they’ve mastered
x=x+1
. It helps both at a higher level, when it’s time to send messages amounting to[odometer setMileCount: [odometer mileCount]+1]
and at a lower level, when it’s time to load up an accumulator, add to it, and store it back somewhere. Withx=x+1
, they’ve seen incrementing as a nontrivial combination of access, addition, and assignment.Well. That Markdown-to-HTML translation was… less than graceful. *chagrin*
(It’s not that bad; you’re at the whim of my theme set-up.)
Thanks for the rundown of operators, and how you approach teaching them.
There is a line where terse-ness makes things more readable, and where it makes things less readable. I feel like the ++ operator is right on that line, and I can’t argue too much with either point, in terms of readability.
Objective-C, as a style, in general, wants things to be less terse. If you love Objective C, you are probably going to favor a less terse form of expression.
But “side effects”, don’t get me started on side effects and Objective C, which is nothing but a horrible steaming pile of memory management related secret rules and side effects.
We already know your dislike of Obj-C as a hybrid language. :D I guess my point is that since it is a hybrid, it’s really useful to learn “both languages” as it were.
What does “It matters because Objective-C Is Still C (Not Java!)” have to do with anything? These operators function the same in Java. Not to mention, Java’s roots are in C.
Mark, “Objective-C Is Still C (Not Java!)” is the name of another blog post. That’s all.
(The point of that other post is that — for better or worse, depending on your point of view at the moment — Obj-C is a superset of C. “Roots” is not the same as “superset”.)
Did I miss it, or does this article not actually name a reason to prefer ++x over x++ in C or Objective-C other than “real programmers use ++x and will think less of you”? (appeal to authority)
The last sentence alludes to avoiding side-effects, but that applies to both ++x and x++.
So why does usage of x++ “show” unfamiliarity with the language (rather than unfamiliarity with a convention used by a certain group of C developers, which in my experience isn’t even the majority.).
Peter,
I’m an enneagram type one personality. The unhealthy side of my type shows up as self-righteous perfectionism.
But I did say it was a rant.
On the other hand…
Objective-C programmers don’t use much of the C standard library, so I don’t expect much familiarity there. But with such a small set of operators, I do expect Objective-C programmers to show competence with C operators. Why anyone would post-increment when they mean pre-increment is a mystery to me.
At least I haven’t found anyone re-implementing modulo.
Yet.
;)
There is perfectionism, and then there is OCD. Considering that ++c vs c++ makes no difference unless used in a assignment, I believe it’s a case of the latter. Take it from a man who barely refrains from threatening people over poor newline management :)