Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use ++i instead of i++ in cases where the value is not used anywhere else in the statement?

Tags:

c++

operators

I'm well aware that in C++

int someValue = i++;
array[i++] = otherValue;

has different effect compared to

int someValue = ++i;
array[++i] = otherValue;

but every once in a while I see statements with prefix increment in for-loops or just by their own:

for( int i = 0; i < count; ++i ) {
     //do stuff
}

or

for( int i = 0; i < count; ) {
    //do some stuff;
    if( condition ) {
        ++i;
    } else {
        i += 4;
    }
}

In the latter two cases the ++i looks like an attempt to produce smarty-looking code. Am I overseeing something? Is there a reason to use ++i instead of i++ in the latter two cases?

like image 464
sharptooth Avatar asked Sep 08 '09 08:09

sharptooth


People also ask

How is if statement is different from the IF ELSE statement?

With the if statement, a program will execute the true code block or do nothing. With the if/else statement, the program will execute either the true code block or the false code block so something is always executed with an if/else statement.

Can you put an if statement in a case?

The short answer is yes, you can nest an if inside of swtich / case statement (or vice versa).

When should you use the SELECT Case statement?

A Select Case statement allows a variable to be tested for equality against a list of values. Each value is called a case, and the variable being switched on is checked for each select case.

Can we have case without else?

The CASE statement always goes in the SELECT clause. CASE must include the following components: WHEN , THEN , and END . ELSE is an optional component.


4 Answers

Look at possible implementations of the two operators in own code:

// Pre-increment
T*& operator ++() {
    // Perform increment operation.
    return *this;
}

// Post-increment
T operator ++(int) {
    T copy = *this;
    ++*this;
    return copy;
}

The postfix operator invokes the prefix operator to perform its own operation: by design and in principle the prefix version will always be faster than the postfix version, although the compiler can optimize this in many cases (and especially for builtin types).

The preference for the prefix operator is therefore natural; it’s the other that needs explanation: why are so many people intrigued by the use of the prefix operator in situations where it doesn’t matter – yet nobody is ever astonished by the use of the postfix operator.

like image 99
Konrad Rudolph Avatar answered Oct 21 '22 09:10

Konrad Rudolph


If we ignore force of habit, '++i' is a simpler operation conceptually: It simply adds one to the value of i, and then uses it.

i++ on the other hand, is "take the original value of i, store it as a temporary, add one to i, and then return the temporary". It requires us to keep the old value around even after i has been updated.

And as Konrad Rudolph showed, there can be performance costs to using i++ with user-defined types.

So the question is, why not always just default to ++i?

If you have no reason to use `i++´, why do it? Why would you default to the operation which is more complicated to reason about, and may be slower to execute?

like image 31
jalf Avatar answered Oct 21 '22 10:10

jalf


As you noted - it does not matter to the result.

There is a performance consideration for non-primitive types.

Also semantically using pre-increment is usually clearer in showing the intention of a test when the return value is used, so its better to use it habitually than post-increment to avoid accidentally testing the old value.

like image 7
Timothy Pratley Avatar answered Oct 21 '22 10:10

Timothy Pratley


There is one reason, and it has to do with overloaded operators. In an overloaded postincrement function, the function must remember the previous value of the object, increment it, and then return the previous value. In a preincrement function, the function can simply increment the object and then return a reference to itself (its new value).

In the case of an integer, the above probably won't apply because the compiler knows the context in which the increment is being done, and will generate appropriate increment code in either case.

like image 4
Greg Hewgill Avatar answered Oct 21 '22 09:10

Greg Hewgill