Argg!!! Classes!

Started by
15 comments, last by body electric 19 years, 7 months ago
Quote:Original post by graveyard filla
anyway, my question is, is it true that doing i++ is actually slower? i mean, isnt this a micro-optimization? i use i++ for every for loop in the 50 + files of my game...


Think what does pre/post increment actually do? pre-increment is pretty obvious it moves up one and returns the value but post increment isn't so much. Post increment returns a copy of the value then increments the original so imagine how this would be implemenated for a iterator type for a list:

....//pre-incrementiterator& operator++() {   node = node->next;   return *this;}//post-incrementiterator operator++(int) {    iterator tmp = *this;    node  = node->next;    return tmp;}


but for built-in types shouldn't be any real concern.
Advertisement
Hmm, did not know these things. Thanks for the help guys, and I guess this just shows that VB is a bit too dumb downed..

Now that you guys brought these things up, I got some questions for ya's! First off, if i++ is slower then ++i, is i=i+1 slower then ++i?

Also, I don't see why != is bad.

Quote:
NO! the second part of the for loop means run _until_ this contion fails. your check fails before it even runs once.


Well, if that is correct, would i!=max mean that once i=max, i!=max would return false, and while i was not equal to max, i!=max would return true?

Thanks guys for your help :)
When you have to work at a lower level, i.e. with integer loop counters, using < (or <= or > or >=) is good defensive coding practice, to guard against the possibility that you "skip over" the loop condition. There might be a valid reason why you want to modify the counter variable within the loop, for example. Consider:
void handleUpToNThings(Thing[] things, int n) {  for (int i = 0; i < n; ++i) {    things.handle();    if weird_condition(thing) i += 5;  }}

There's no guarantee here that i will ever be equal to n, and there isn't even a good way of fixing that fact, so we use '<'. Otherwise we could get an infinite loop (and in this case, run out of things and crash with a segfault).

Iterators aren't necessarily logically ordered (just comparable for equality), so you're kinda stuck with '==' and '!='. However, they're also safer, and designed to handle that situation. (i.e., they'll have overloads for operator + and so on that prevent serious problems.)

RE i++ vs ++i: "i++" is idiomatic C for a loop counter, from back when it didn't really matter (because there were no classes around) and I guess people figured it looked better. On any half-decent compiler these days (i.e. not written at 2am by a group of drunken university students), they should compile to basically the same code for primitive types (assuming you're not actually using the 'return value' of the increment). However, for any classes or structs, this optimization is impossible, because the language can't even guarantee that the two overloaded operators have anything to do with each other. (Of course, it can't guarantee that a function called add() does anything having to do with addition, either; but IMHO I still think the design of C++'s operator overload scheme could use some work. Even though I do miss having overloads in Java.)

'i = i + 1' will again optimize to the same thing for primitive types. But note that i++ and ++i are not mere statements, but expressions:

j = i++; // Effectively: j = i; i = i + 1;j = ++i; // Effectively: i = i + 1; j = i;
Quote:Original post by bobthebobert
Now that you guys brought these things up, I got some questions for ya's! First off, if i++ is slower then ++i, is i=i+1 slower then ++i?

No, it is exactly identical. Maybe a long time ago, a bad compiler would generate slower code (which is the main reason we have increment/decrement operators), but now they're the same. "return i=i+1" will return the new value of i; it is identical in both speed and operation to "return ++i".

Quote:Also, I don't see why != is bad.

A simple example is when dealing with floating-point numbers (decimals). Say you have this:
for( float F = 0; F != 1; F += 0.1 ){ /* ... */ }

0.1 isn't stored precisely in floating-point format; as a result, F will never ever equal 1. The closest it comes will be something like 1.000034 maybe. You need to say "< 1" instead.
~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
Quote:Original post by bobthebobert
Also, I don't see why != is bad.


It is bad because of the situation, not because it's bad as a codingstyle.

This is the != situation: (start: 0; you-want-to-loop: 6;)

1 2 3 4 5 6 | 7 8 9 10 11 12

This is the < situation: (start: 0; you-want-to-loop: 6;)

1 2 3 4 5 6 | x x x x~ x~ x~

As you can see, the < situation reaches the breaking-statement (displayed as |) and quits (displayed as x). If for some reason the loop SKIPS the breaking-statement, it will not run in this case, because anything beyond the statement is x.
BUT if you look at the != situation, anything beyond the breaking-statement is still valid.
So if anything would've caused the loop to jump after the statement, you'd get a) an endless loop, or b) an access violation.

Back to your first situation, you had ==, and as you should know in C++ when you declare an array like this: char Arr[6]; The sixth element is 5 (because the first is 0) so if you access 6 (which is actually the seventh element) you're accessing other memory, aka you caused a memory access violation.
I see what you guys are saying about the != thing, but for what I am using it for now is ok I think. In all of my for loops where I use !=, not once do I change the variable in the code which in some way might make the code continue infinetly. (AKA, if I use ++i, in my loop code I never change the variable i). However I do see what you guys are saying, and appreciate your help.
I think for ints you will generally be okay, but keep in mind that even if you don't do anything that will obviously cause your variable to "skip," it can still happen with floating point numbers, simply becuase some decimals cannot possibly be represented with a finite number of binary bits.

To illustrate this problem in binary, consider the same problem in decimals. If you wanted to add 1/3 to i each iteration until i was equal to 1, the loop would never break! 1/3 is going to round at some point, say at 0.3333. Thus,

3 * 0.3333 == 0.9999 != 1

Binary arithmatic is even less forgiving, and you must expect rounding to occur anytime floating point numbers enter an equation.

So, again, ints might be safe, but get out of the habit of using != becuase it won't be obvious later when you use floats and something doesn't work.
Praise Gaia!

This topic is closed to new replies.

Advertisement