I was wondering if the increment and decrement operators ( ++ -- ) have more purpose to it than its plain use to make the code more simple
maybe:
i++;
is more efficient than:
i = i + 1;
?
I was wondering if the increment and decrement operators ( ++ -- ) have more purpose to it than its plain use to make the code more simple
maybe:
i++;
is more efficient than:
i = i + 1;
?
In many ways, the main purpose of the operators is backwards
compatibility. When C++ was being designed, the general rule
was to do what C did, at least for non-class types; if C hadn't
had ++
and --
, I doubt C++ would have them.
Which, of course, begs the question. It's inconceivable that
they would generate different code in a modern compiler, and
it's fairly inconceivable that the committee would introduce
them for optimization reasons (although you never
know—move semantics were introduced mainly for
optimization reasons). But back in the mid-1970s, in the
formative years of C? It was generally believed, at the time,
that they were introduced because they corresponded to machine
instructions on the PDP-11. On the other hand, they were
already present in B. C acquired them from B. And B was an
interpreted language, so there was no issue of them
corresponding to machine instructions. My own suspicion, which
applies to many of the operators (&
, rather than and
, etc.)
is that they were introduced because development at the time was
largely on teletypes (tty's), and every character you output to
a teletype made a lot of unpleasant noise. So the less
characters you needed, the better.
As to the choice between ++ i;
, i += 1;
and i = i + 1;
:
there is a decided advantage to not having to repeat the i
(which can, of course, be a more or less complex expression), so
you want at least i += 1;
. Python stops there, if for no
other reason than it treats assignment as a statement, rather
than as the side effect of an arbitrary expression. With over
30 years of programming in C and C++ under my belt, I still feel
that ++ i
is missing when programming in Python, even though I
pretty much restrict myself in C++ to treating assignment as a
statement (and don't embed ++ i
in more complicated
expressions).
The two examples you gave will almost certainly compile to exactly the same machine code. Compilers are very smart. Understand that a compiler rarely executes the code you actually wrote. It will twist it and mould it to improve performance. Any modern compiler will know that i++;
and i = i + 1;
are identical (for an arithmetic type) and generate the same output.
However, there is a good reason to have both, other than just code readability. Conceptually, incrementing a value many times and adding to a value are different operations - they are only the same here because you are adding 1. An addition, such as x + 3
, is a single operation, whereas doing ++++++x
represents three individual operations with the same effect. Of course, a smart compiler will also know that for an object of arithmetic type, x
, it can do N
increments in constant time just by doing x + N
.
However, the compiler can't make this assumption if x
is of class type with an overloaded operator+
and operator++
. These two operators may do entirely different things. In addition, implementing an operator+
as a non-constant time operation would give the wrong impression.
The importance of having both becomes clear when we're dealing with iterators. Only Random Access Iterators support addition and subtraction. For example, a standard raw pointer is a random access iterator because you can do ptr + 5
and get a pointer to the 5th object along. However, all other types of iterators (bidirectional, forward, input) do not support this - you can only increment them (and decrement a bidirectional iterator). To get to the 5th element along with a bidirectional iterator, you need to do ++
five times. That's because an addition represents a constant time operation but many iterators simply cannot traverse in constant time. Forcing multiple increments shows that it's not a constant time operation.
Performance depends on the type of i
.
If it's a built-in type, then optimizers will "notice" that your two statements are the same, and emit the same code for both.
Since you used post-increment (and ignoring your semi-colons), the two expressions have different values even when i
is a built-in type. The value of i++
is the old value, the value of i = i + 1
is the new value. So, if you write:
j = i++;
k = (i = i + 1);
then the two are now different, and the same code will not be emitted for both.
Since the post-condition of post-increment is the same as pre-increment, you could well say that the primary purpose of the post-increment operator is that it evaluates to a different value. Regardless of performance, it makes the language more expressive.
If i
has class type with overloaded operators then it might not be so simple. In theory the two might not even have the same result, but assuming "sensible" operators i + 1
returns a new instance of the class, which is then move-assigned (in C++11 if the type has a move assignment operator) or copy-assigned (in C++03) to i
. There's no guarantee that the optimizer can make this as efficient as what operator++
does, especially if the operator overload definitions are off in another translation unit.
Some types have operator++
but not operator+
, for example std::list<T>::iterator
. That's not the reason ++
exists, though, since it existed in C and C has no types with ++
but not +
. It is a way that C++ has taken advantage of it existing.
Both would produce same machine instruction(s) in optimized code by a decent compiler.
If the compiler sees i++
is more efficient,then it will convert i=i+1
to i++
, or vice-versa. The result will be same no matter what you write.
I prefer ++i
. I never write i=i+1
.
No, it is simply to make typing simple, and to get simpler looking syntax.
When they are both compiled, they are reduced to the same compiled code, and run at the same speed.
The ++
or --
operator allows it to be combined into other statements rather than i=i+1
. For e.g. while (i++ < 10)
allows a while loop check and an increment to be done after it. It's not possible to do that with i=i+1
.
The ++
or --
operator can be overloaded in other classes to have other meanings or to do increments and decrements with additional actions. Please see this page for more info.
They both are not exactly same , though functionally they are same, there is a difference in precedencei++
has more precedence(more priority) than i=i+1
Try to replace ++i or i++ in some more complicated expression. You're going to have difficulties with the preincrement/postincrement feature. You're going to need to split the expression into multiple ones. It's like ternary operator. It is equivalent, the compiler may perform some optimizations regardless on the way you enter the code, but ternary operator and preincrement/postincrement syntax just save you space and readability of the code.
The difference between i++
and i = i + 1
is that the first expression only evaluates i
once and the second evaluates it twice. Consider:
int& f() {
static int value = 0;
std::cout << "f() called\n";
return value;
}
f()++; // writes the message once
f() = f() + 1; // writes the message twice
And if f()
returns different references on different calls, the two expressions have vastly different effects. Not that this is good design, of course...