24

Possible Duplicate:
Difference between i++ and ++i in a loop?

Can anyone explain what's the difference between those:

for(unsigned col = 0; col < n; ++col, num_to_fill >>= 1U)
{

    for(unsigned row = num_to_fill; row < (1U << n); row += (num_to_fill * 2))
    {
        std::fill_n(&output[col][row], num_to_fill, 1);
    }
}

and

for(unsigned col = 0; col < n; col++, num_to_fill >>= 1U)
{

    for(unsigned row = num_to_fill; row < (1U << n); row += (num_to_fill * 2))
    {
        std::fill_n(&output[col][row], num_to_fill, 1);
    }
}

When col=0 , In ex.1 Output[col][row] will be output[1][row] and In ex.2 Output[col][row] will be output[0][row] . Am I right ?

Question 2 : Would using >>= 1U instead of /= 2 make any difference ?

Community
  • 1
  • 1
Ahmed
  • 3,398
  • 12
  • 45
  • 64
  • 1
    If I remember correctly, in this case it doesn't make any difference. It does make a difference when using the variable as an `R-Value` like so: `a = b++;` or `a = ++b;` – Igor Zinov'yev Aug 22 '10 at 12:07
  • 1
    The answers for that question are mostly incorrect, Greg. They answer what post and pre incrementation are, **not** how they work in a loop - indeed many of the are misleading in that they apply that it does make a difference because they use a misleading syntax for their loops (`int i = 0; foreach(randomOtherThing in randomOtherThings)`...) – Stephen Aug 22 '10 at 12:14
  • Ok . What about the 2nd question ? – Ahmed Aug 22 '10 at 12:14
  • @Stephen: That's not the issue with duplicates. The issue is the question has been asked before. If he had just Question #2, then it would not be a duplicate. –  Aug 22 '10 at 12:19
  • 1
    @0A0D And yet giving the OP a link to that question, which has the **wrong** answer marked as the correct one, would somehow suffice to improve his understanding? I thought SO was meant to be about learning and helping others to learn. It is very likely that someone could be mislead by the linked question, into thinking that pre or post incrementing *in the loop* did actually affect the value of the counter inside the loop. Claiming this is a duplicate of that particular question does not encourage learning, it merely shows the sometimes far too pedantic nature of SO users. – Stephen Aug 22 '10 at 12:22
  • @Stephen: I see this exact same question asked a couple of times a week on SO, and it's all I can do to try to leverage existing answers. There are undoubtedly closer matches; feel free to find one and mark as a duplicate. – Greg Hewgill Aug 22 '10 at 12:25
  • @Stephen: If that answer is wrong, then comment on it, answer it yourself and make it better - but certainly don't encourage asking the same question over and over. Eventually all these duplicates will get merged. –  Aug 22 '10 at 12:27
  • @Ahmed: For your second question, see http://stackoverflow.com/questions/2987741/what-is-the-difference-between-bit-shifting-and-arithmetical-operations – Greg Hewgill Aug 22 '10 at 12:35
  • +1 for using "unsigned int" for looping – Chubsdad Aug 22 '10 at 12:37
  • @Greg : Excellent link . @Others who are fighting : When I did a search for post and prefix operators it didn't give me the results you linked so that's why I typed my question . Sorry for writing a dupe but I didn't know . – Ahmed Aug 22 '10 at 12:38
  • Another possible duplicate: http://stackoverflow.com/questions/1918196/why-doesnt-changing-the-pre-to-the-post-increment-at-the-iteration-part-of-a-for – Greg Hewgill Aug 22 '10 at 21:48

2 Answers2

31

It does not make any difference to the value of col within the loop - assuming col is a primitive value. If col was a class, the prefix and postfix '++' operators might be overloaded to do two different things, although I would consider it bad practice. Consider the following example:

#include <iostream>

using namespace std;

int main() {
    for(int i = 0; i < 10; i++) {
        cout << i << endl;
    }

    cout << endl;

    for(int i = 0; i < 10; ++i) {
        cout << i << endl;
    }

}

Both of these just print out 0 to 9, despite the fact that you pre-increment in one, and post-increment in the other. The incrementation of i happens at the end of each run of the loop whether or not you use pre or post increment. I believe pre-incrementing is more efficient, since - and I may be wrong here - the compiler does not then need to use a temporary variable1., but this would only be noticeable if you are looping for a very long time (and of course 'More computing sins are committed in the name of efficiency than for any other single reason'.)

As for question 2:

Question 2 : Would using >>= 1U instead of =/2 make any difference ?

Unlikely. Bit shifting would be faster if the compiler did not optimise, but chances are that your compiler will optimise this into a bit shift.

As a side note, I generally find doing unsigned variableName (that is, dropping the int) bad practice - although C++ will shove in an int anywhere one is missing, it is less readable to me.

1.: Stephen in the comments (a different Stephen ;) ) notes that - "Pre-increment is more efficient for standard library container iterators, but it's no different for primitive types, since copying an integer is cheaper than copying a larger iterator (in particular std::set and std::map iterators)."

Stephen
  • 6,027
  • 4
  • 37
  • 55
  • That was comprehensive . – Ahmed Aug 22 '10 at 12:18
  • 2
    Pre-increment is more efficient for standard library container iterators, but it's no different for primitive types, since copying an integer is cheaper than copying a larger iterator (in particular std::set and std::map iterators). p.s. I am not the 'Stephen' that produced this answer – Stephen Cross Aug 22 '10 at 12:20
  • 1
    @Stephen Thank you, other Stephen. I shall include your answer. And then credit 'Stephen', of course :p. – Stephen Aug 22 '10 at 12:23
  • I though that multiplication can lead to overflow related concerns whereas << 1 won't. So isn't (num_to_fill << 1) better than (num_to_fill * 2) assuming num_to_fill is also an unsigned int? – Chubsdad Aug 22 '10 at 12:43
  • With modern compilers you don't need to worry about all this "more efficient" stuff, the optimizer is probably way smarter than you. In any case, if you're trying to optimize for efficiency - do profile to first make sure you need to optimize and second you are making things better. Write readable code instead of "optimal", you'll thank yourself later. – inkredibl May 07 '21 at 17:12
2

There is no difference for unsigned. However, there would be a difference for classes with overloaded operator++, because it would call its different overloads (usually, the postfix operator creates a copy of the class, which means it may be slower).

Would using >>= 1U instead of /=2 make any difference?

Probably not. Its semantics are the same for unsigned, and the compilers usually treat them equally and can change one into another if it's faster.

jpalecek
  • 47,058
  • 7
  • 102
  • 144
  • I wonder why the code writer used it . – Ahmed Aug 22 '10 at 12:17
  • It may describe the overall operation better. For instance, if the variable that's being divided (or shifted) is some sort of bitvector, in which arithmetic division is a meaningless concept, but shifting is meaningful. – Nathan Fellman Aug 22 '10 at 12:25