-1

My actual concern is about whether the expressions of ++i;, i = i + 1; and i += 1; are one-hundred percent equivalent to each other, if i is defined before.

  1. ++i; - i gets immediately incremented by 1 within the statement, as opposed to i++; where the incremetation by 1 is done after the expression.
  2. i = i + 1; - i gets immediately incremented by 1 within the statement.
  3. i += 1; - i gets immediately incremented by 1 within the statement.

Are there *any kind of differences between those expressions or are they 100% equivalent?

*"Any" may refer to syntax and semantics, but also to performance and memory-management.

2 Answers2

7

C

In C, i = i+1 and i += 1 are not equivalent if i is an atomic type, because the compound assignment is a read-modify-write operation with memory_order_seq_cst semantics, per C 2018 6.5.16.2 3. I also cannot say the C standard is completely clear on the semantics of i = i+1 and i += 1 in regard to volatile objects. Otherwise, ++i, i = i+1, and i += 1 are equivalent, given that i is merely an identifier, not a placeholder for any more complicated expression.

C++

In C++, the operations are not equivalent. Proof:

This program:

#include <iostream>


class SensitiveToOperations
{
public:
    SensitiveToOperations operator ++() { std::cout << "Preincrement.\n"; return *this; }
    SensitiveToOperations operator +(int that) const { std::cout << "Addition.\n"; return *this; }
    SensitiveToOperations operator =(SensitiveToOperations that) { std::cout << "Assignment.\n"; return *this; }
    SensitiveToOperations operator +=(int that) { std::cout << "AdditionAssignment.\n"; return *this; }
};


int main(void)
{
    SensitiveToOperations i;
    ++i;
    i = i + 1;
    i += 1;
}

produces this output:

Preincrement.
Addition.
Assignment.
AdditionAssignment.

thus showing that different results may be obtained for the different operations.

For fundamental types, the operations may be largely equivalent, but I am not qualified to speak to C++ semantics with regard to atomic or volatile.

Community
  • 1
  • 1
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
  • The canonical implementation of increment and decrement operators for integer types, is the use of assignment and addition/subtraction, thus we assume `x = ++i` is equal to `i = i + 1; x = i`. The use of `i` further implies an integer type, but I guess there are some uses for overriding these operators with different behaviour. Hope I won't encounter such custom behaviour on integers, though. – Andreas is moving to Codidact Feb 09 '20 at 12:37
4

In C, ++i is equivalent to (i += 1)

C11 Draft Standard 6.5.3.1p2:

The expression ++E is equivalent to (E+=1).

The expression i += 1 is equivalent to i = i + 1, except that in the first case i is guaranteed to be evaluated only one time. In function calls i += 1 results in a single evaluation.

C11 Draft Standard 6.5.16.2p3:

A compound assignment of the form E1 op = E2 is equivalent to the simple assignment expression E1 = E1 op (E2), except that the lvalue E1 is evaluated only once, and with respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation. If E1 has an atomic type, compound assignment is a read-modify-write operation with memory_order_seq_cst memory order semantics.

You might expect performance to be marginally better for ++i, given that i is evaluated only once in this expression, but this really comes down to implementation details and how well your compiler optimizes. Performance and memory-management issues are outside of the purview of the tag.

ad absurdum
  • 19,498
  • 5
  • 37
  • 60