This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Undefined Behavior and Sequence Points
I'm not sure if this is a gcc bug or not, so I'll ask:
unsigned int n = 0;
std::cout << n++ << n << ++n;
gcc gives the extremely strange result:
"122" which AFAICT is impossible. Because << is left associative, it should be the same as:
operator<<(operator<<(operator<<(std::cout, n++), n), ++n)
and because there is a sequence point before and after evaluating arguments, n is never modified twice (or even accessed) between two sequence points -- so it shouldn't be undefined behaviour, just the order of evaluation unspecified.
So AFAICT valid results would be:
111
012
002
101
and nothing else
There is a sequence point between evaluating arguments and calling a function. There is no sequence point between evaluating different arguments.
Let's look at the outermost function call:
operator<<(operator<<(operator<<(std::cout, n++), n), ++n)
The arguments are
operator<<(operator<<(std::cout, n++), n)
and
++n
It is unspecified which of these is evaluated first. It's also allowed that the first argument is partially evaluated when the second argument is evaluated.
From the standard, section [intro.execution] (wording from draft 3225):
If A is not sequenced before
B and B is not sequenced before A, then A and B are unsequenced. [ Note: The execution of unsequenced
evaluations can overlap. — end note ]
Except where noted, evaluations of operands of individual operators and of subexpressions of individual
expressions are unsequenced. [ Note: In an expression that is evaluated more than once during the execution
of a program, unsequenced and indeterminately sequenced evaluations of its subexpressions need not be
performed consistently in different evaluations. — end note ] The value computations of the operands of an
operator are sequenced before the value computation of the result of the operator. If a side effect on a scalar
object is unsequenced relative to either another side effect on the same scalar object or a value computation
using the value of the same scalar object, the behavior is undefined.
Because you have multiple operations with side effects on the same scalar object which are unsequenced with respect to each other, you're in that realm of undefined behavior, and even 999 would be a permissible output.
The first rule of compiler bugs: it's probably not a compiler bug but a misunderstanding on your part. Using the postfix and prefix operators in the same statement results in undefined behavior. Try using the -Wall option to give you more warnings and show you the potential pitfalls in your code.
Let's see what GCC 4.2.1 tells us when we ask for warnings about test.cpp:
#include <iostream>
int main() {
unsigned int n = 0;
std::cout << n++ << n << ++n << std::endl;
return 0;
}
When we compile:
$ g++ -Wall test.cpp -o test
test.cpp: In function ‘int main()’:
test.cpp:5: warning: operation on ‘n’ may be undefined
Your code its an example of why in some books remark that experienced programmers don't like that(++,--) operator overload, even other languages (ruby) has not implemented ++ or --.
Related
What are "sequence points"?
What is the relation between undefined behaviour and sequence points?
I often use funny and convoluted expressions like a[++i] = i;, to make myself feel better. Why should I stop using them?
If you've read this, be sure to visit the follow-up question Undefined behavior and sequence points reloaded.
(Note: This is meant to be an entry to Stack Overflow's C++ FAQ. If you want to critique the idea of providing an FAQ in this form, then the posting on meta that started all this would be the place to do that. Answers to that question are monitored in the C++ chatroom, where the FAQ idea started out in the first place, so your answer is very likely to get read by those who came up with the idea.)
C++98 and C++03
This answer is for the older versions of the C++ standard. The C++11 and C++14 versions of the standard do not formally contain 'sequence points'; operations are 'sequenced before' or 'unsequenced' or 'indeterminately sequenced' instead. The net effect is essentially the same, but the terminology is different.
Disclaimer : Okay. This answer is a bit long. So have patience while reading it. If you already know these things, reading them again won't make you crazy.
Pre-requisites : An elementary knowledge of C++ Standard
What are Sequence Points?
The Standard says
At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations
shall be complete and no side effects of subsequent evaluations shall have taken place. (§1.9/7)
Side effects? What are side effects?
Evaluation of an expression produces something and if in addition there is a change in the state of the execution environment it is said that the expression (its evaluation) has some side effect(s).
For example:
int x = y++; //where y is also an int
In addition to the initialization operation the value of y gets changed due to the side effect of ++ operator.
So far so good. Moving on to sequence points. An alternation definition of seq-points given by the comp.lang.c author Steve Summit:
Sequence point is a point in time at which the dust has settled and all side effects which have been seen so far are guaranteed to be complete.
What are the common sequence points listed in the C++ Standard?
Those are:
at the end of the evaluation of full expression (§1.9/16) (A full-expression is an expression that is not a subexpression of another expression.)1
Example :
int a = 5; // ; is a sequence point here
in the evaluation of each of the following expressions after the evaluation of the first expression (§1.9/18) 2
a && b (§5.14)
a || b (§5.15)
a ? b : c (§5.16)
a , b (§5.18) (here a , b is a comma operator; in func(a,a++) , is not a comma operator, it's merely a separator between the arguments a and a++. Thus the behaviour is undefined in that case (if a is considered to be a primitive type))
at a function call (whether or not the function is inline), after the evaluation of all function arguments (if any) which
takes place before execution of any expressions or statements in the function body (§1.9/17).
1 : Note : the evaluation of a full-expression can include the evaluation of subexpressions that are not lexically
part of the full-expression. For example, subexpressions involved in evaluating default argument expressions (8.3.6) are considered to be created in the expression that calls the function, not the expression that defines the default argument
2 : The operators indicated are the built-in operators, as described in clause 5. When one of these operators is overloaded (clause 13) in a valid context, thus designating a user-defined operator function, the expression designates a function invocation and the operands form an argument list, without an implied sequence point between them.
What is Undefined Behaviour?
The Standard defines Undefined Behaviour in Section §1.3.12 as
behavior, such as might arise upon use of an erroneous program construct or erroneous data, for which this International Standard imposes no requirements 3.
Undefined behavior may also be expected when this
International Standard omits the description of any explicit definition of behavior.
3 : permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or with-
out the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).
In short, undefined behaviour means anything can happen from daemons flying out of your nose to your girlfriend getting pregnant.
What is the relation between Undefined Behaviour and Sequence Points?
Before I get into that you must know the difference(s) between Undefined Behaviour, Unspecified Behaviour and Implementation Defined Behaviour.
You must also know that the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified.
For example:
int x = 5, y = 6;
int z = x++ + y++; //it is unspecified whether x++ or y++ will be evaluated first.
Another example here.
Now the Standard in §5/4 says
Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression.
What does it mean?
Informally it means that between two sequence points a variable must not be modified more than once.
In an expression statement, the next sequence point is usually at the terminating semicolon, and the previous sequence point is at the end of the previous statement. An expression may also contain intermediate sequence points.
From the above sentence the following expressions invoke Undefined Behaviour:
i++ * ++i; // UB, i is modified more than once btw two SPs
i = ++i; // UB, same as above
++i = 2; // UB, same as above
i = ++i + 1; // UB, same as above
++++++i; // UB, parsed as (++(++(++i)))
i = (i, ++i, ++i); // UB, there's no SP between `++i` (right most) and assignment to `i` (`i` is modified more than once btw two SPs)
But the following expressions are fine:
i = (i, ++i, 1) + 1; // well defined (AFAIK)
i = (++i, i++, i); // well defined
int j = i;
j = (++i, i++, j*i); // well defined
Furthermore, the prior value shall be accessed only to determine the value to be stored.
What does it mean? It means if an object is written to within a full expression, any and all accesses to it within the same expression must be directly involved in the computation of the value to be written.
For example in i = i + 1 all the access of i (in L.H.S and in R.H.S) are directly involved in computation of the value to be written. So it is fine.
This rule effectively constrains legal expressions to those in which the accesses demonstrably precede the modification.
Example 1:
std::printf("%d %d", i,++i); // invokes Undefined Behaviour because of Rule no 2
Example 2:
a[i] = i++ // or a[++i] = i or a[i++] = ++i etc
is disallowed because one of the accesses of i (the one in a[i]) has nothing to do with the value which ends up being stored in i (which happens over in i++), and so there's no good way to define--either for our understanding or the compiler's--whether the access should take place before or after the incremented value is stored. So the behaviour is undefined.
Example 3 :
int x = i + i++ ;// Similar to above
Follow up answer for C++11 here.
This is a follow up to my previous answer and contains C++11 related material..
Pre-requisites : An elementary knowledge of Relations (Mathematics).
Is it true that there are no Sequence Points in C++11?
Yes! This is very true.
Sequence Points have been replaced by Sequenced Before and Sequenced After (and Unsequenced and Indeterminately Sequenced) relations in C++11.
What exactly is this 'Sequenced before' thing?
Sequenced Before(§1.9/13) is a relation which is:
Asymmetric
Transitive
between evaluations executed by a single thread and induces a strict partial order1
Formally it means given any two evaluations(See below) A and B, if A is sequenced before B, then the execution of A shall precede the execution of B. If A is not sequenced before B and B is not sequenced before A, then A and B are unsequenced 2.
Evaluations A and B are indeterminately sequenced when either A is sequenced before B or B is sequenced before A, but it is unspecified which3.
[NOTES]
1 : A strict partial order is a binary relation "<" over a set P which is asymmetric, and transitive, i.e., for all a, b, and c in P, we have that:
........(i). if a < b then ¬ (b < a) (asymmetry);
........(ii). if a < b and b < c then a < c (transitivity).
2 : The execution of unsequenced evaluations can overlap.
3 : Indeterminately sequenced evaluations cannot overlap, but either could be executed first.
What is the meaning of the word 'evaluation' in context of C++11?
In C++11, evaluation of an expression (or a sub-expression) in general includes:
value computations (including determining the identity of an object for glvalue evaluation and fetching a value previously assigned to an object for prvalue evaluation) and
initiation of side effects.
Now (§1.9/14) says:
Every value computation and side effect associated with a full-expression is sequenced before every value computation and side effect associated with the next full-expression to be evaluated.
Trivial example:
int x;
x = 10;
++x;
Value computation and side effect associated with ++x is sequenced after the value computation and side effect of x = 10;
So there must be some relation between Undefined Behaviour and the above-mentioned things, right?
Yes! Right.
In (§1.9/15) it has been mentioned that
Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced4.
For example :
int main()
{
int num = 19 ;
num = (num << 3) + (num >> 3);
}
Evaluation of operands of + operator are unsequenced relative to each other.
Evaluation of operands of << and >> operators are unsequenced relative to each other.
4: In an expression that is evaluated more than once during the execution
of a program, unsequenced and indeterminately sequenced evaluations of its subexpressions need not be performed consistently in different evaluations.
(§1.9/15)
The value computations of the operands of an
operator are sequenced before the value computation of the result of the operator.
That means in x + y the value computation of x and y are sequenced before the value computation of (x + y).
More importantly
(§1.9/15) If a side effect on a scalar object is unsequenced relative to either
(a) another side effect on the same scalar object
or
(b) a value computation using the value of the same scalar object.
the behaviour is undefined.
Examples:
int i = 5, v[10] = { };
void f(int, int);
i = i++ * ++i; // Undefined Behaviour
i = ++i + i++; // Undefined Behaviour
i = ++i + ++i; // Undefined Behaviour
i = v[i++]; // Undefined Behaviour
i = v[++i]: // Well-defined Behavior
i = i++ + 1; // Undefined Behaviour
i = ++i + 1; // Well-defined Behaviour
++++i; // Well-defined Behaviour
f(i = -1, i = -1); // Undefined Behaviour (see below)
When calling a function (whether or not the function is inline), every value computation and side effect associated with any argument expression, or with the postfix expression designating the called function, is sequenced before execution of every expression or statement in the body of the called function. [Note: Value computations and side effects associated with different argument expressions are unsequenced. — end note]
Expressions (5), (7) and (8) do not invoke undefined behaviour. Check out the following answers for a more detailed explanation.
Multiple preincrement operations on a variable in C++0x
Unsequenced Value Computations
Final Note :
If you find any flaw in the post please leave a comment. Power-users (With rep >20000) please do not hesitate to edit the post for correcting typos and other mistakes.
C++17 (N4659) includes a proposal Refining Expression Evaluation Order for Idiomatic C++
which defines a stricter order of expression evaluation.
In particular, the following sentence
8.18 Assignment and compound assignment operators:....
In all cases, the assignment is sequenced after the value
computation of the right and left operands, and before the value computation of the assignment expression.
The right operand is sequenced before the left operand.
together with the following clarification
An expression X is said to be sequenced before an expression Y if every
value computation and every side effect associated with the expression X is sequenced before every value
computation and every side effect associated with the expression Y.
make several cases of previously undefined behavior valid, including the one in question:
a[++i] = i;
However several other similar cases still lead to undefined behavior.
In N4140:
i = i++ + 1; // the behavior is undefined
But in N4659
i = i++ + 1; // the value of i is incremented
i = i++ + i; // the behavior is undefined
Of course, using a C++17 compliant compiler does not necessarily mean that one should start writing such expressions.
I am guessing there is a fundamental reason for the change, it isn't merely cosmetic to make the old interpretation clearer: that reason is concurrency. Unspecified order of elaboration is merely selection of one of several possible serial orderings, this is quite different to before and after orderings, because if there is no specified ordering, concurrent evaluation is possible: not so with the old rules. For example in:
f (a,b)
previously either a then b, or, b then a. Now, a and b can be evaluated with instructions interleaved or even on different cores.
In C99(ISO/IEC 9899:TC3) which seems absent from this discussion thus far the following steteents are made regarding order of evaluaiton.
[...]the order of evaluation of subexpressions and the order in which
side effects take place are both unspecified. (Section 6.5 pp 67)
The order of evaluation of the operands is unspecified. If an attempt
is made to modify the result of an assignment operator or to access it
after the next sequence point, the behavior[sic] is undefined.(Section
6.5.16 pp 91)
Today I came across some code that exhibits different behavior on
clang++ (3.7-git), g++ (4.9.2) and Visual Studio 2013. After some reduction
I came up with this snippet which highlights the issue:
#include <iostream>
using namespace std;
int len_ = -1;
char *buffer(int size_)
{
cout << "len_: " << len_ << endl;
return new char[size_];
}
int main(int argc, char *argv[])
{
int len = 10;
buffer(len+1)[len_ = len] = '\0';
cout << "len_: " << len_ << endl;
}
g++ (4.9.2) gives this output:
len_: -1
len_: 10
So g++ evaluates the argument to buffer, then buffer(..) itself and after that it evaluates the index argument to the array operator. Intuitively this makes sense to me.
clang (3.7-git) and Visual Studio 2013 both give:
len_: 10
len_: 10
I suppose clang and VS2013 evaluates everything possible before it decends into buffer(..). This makes less intuitive sense to me.
I guess the gist of my question is whether or not this is a clear case of undefined behavior.
Edit: Thanks for clearing this up, and unspecified behavior is the term I should have used.
This is unspecified behavior, len_ = len is indeterminately sequenced with respect to the execution of the body of buffer(), which means that one will be executed before the other but it is not specified which order but there is an ordering so evaluations can not overlap therefore no undefined behavior. This means gcc, clang and Visual Studio are all correct. On other hand unsequenced evaluations allow for overlapping evaluations which can lead to undefined behavior as noted below.
From the draft C++11 standard section 1.9 [intro.execution]:
[...]Every evaluation in the calling function (including other function calls) that is not otherwise specifically
sequenced before or after the execution of the body of the called function is indeterminately sequenced with
respect to the execution of the called function.9[...]
and indeterminately sequenced is covered a little before this and says:
[...]Evaluations A and B are indeterminately sequenced when either A
is sequenced before B or B is sequenced before A, but it is unspecified which. [ Note: Indeterminately
sequenced evaluations cannot overlap, but either could be executed first. —end note ]
which is different than unsequenced evaluations:
[...]If A is not sequenced before
B and B is not sequenced before A, then A and B are unsequenced. [ Note: The execution of unsequenced
evaluations can overlap. —end note ][...]
which can lead to undefined behavior (emphasis mine):
Except where noted, evaluations of operands of individual operators and of subexpressions of individual
expressions are unsequenced. [ Note: In an expression that is evaluated more than once during the execution
of a program, unsequenced and indeterminately sequenced evaluations of its subexpressions need not be
performed consistently in different evaluations. —end note ] The value computations of the operands of an
operator are sequenced before the value computation of the result of the operator. If a side effect on a scalar
object is unsequenced relative to either another side effect on the same scalar object or a value computation
using the value of the same scalar object, the behavior is undefined[...]
Pre C++11
Pre C++11 the order of evaluation of sub-expressions is also unspecified but it uses sequence points as opposed to ordering. In this case, there is a sequence point at function entry and function exit which ensures there is no undefined behavior. From section 1.9:
[...]The sequence points at function-entry and function-exit
(as described above) are features of the function calls as evaluated, whatever the syntax of the expression that calls the
function might be.
Nailing down order of evaluation
The different choices made by each compiler may seem unintuitive depending on your perspective and expectations. The subject of nailing down order of evaluation is the subject of EWG issue 158: N4228 Refining Expression Evaluation Order for Idiomatic C++, which is being considered for C++17 but seems controversial based on the reactions to a poll on the subject. The paper covers a much more complicated case from "The C++ Programming Language" 4th edition. Which shows even those with deep experience in C++ can get tripped up.
Well, no, it's not a case of undefined behaviour. It is a case of unspecified behaviour.
It is unspecified whether the expression len_ = len will be evaluated before or after buffer(len+1). From the output you have described, g++ evaluates buffer(len+1) first, and clang evaluates len_ = len first.
Both possibilities are correct, since the order of evaluation of those two sub-expressions is unspecified . Both expressions will be evaluated (so the behaviour does not qualify as being undefined) but the standard does not specify the order.
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 8 years ago.
#include <iostream>
using namespace std;
main(){
int i = 5;
cout << i++ << i--<< ++i << --i << i << endl;
}
The above program compiled with g++ gives output :
45555
While the following program:
int x=20,y=35;
x =y++ + y + x++ + y++;
cout << x<< endl << y;
gives result as
126
37
Can anyone please explain the output.
cout << i++ << i--
is semantically equivalent to
operator<<(operator<<(cout, i++), i--);
<------arg1--------->, <-arg2->
$1.9/15- "When calling a function
(whether or not the function is
inline), every value computation and
side effect associated with any
argument expression, or with the
postfix expression designating the
called function, is sequenced before
execution of every expression or
statement in the body of the called
function. [ Note: Value computations
and side effects associated with
different argument expressions are
unsequenced. —end note ]
C++0x:
This means that the evaluation of the arguments arg1/arg2 are unsequenced (neither of them is sequenced before the other).
The same section in the draft Standard also states,
If a side effect on a scalar object is
unsequenced relative to either another
side effect on the same scalar object
or a value computation using the value
of the same scalar object, the
behavior is undefined.
Now there is a sequence point at the semicolon at the end of the full expression below
operator<<(operator<<(cout, i++), i--);
^ the interesting sequence point is right here
As is clear, evaluation of both arg1 and arg2 lead to side effect on the scalar variable 'i', and as we saw above, the side effects are unsequenced.
Therefore the code has undefined behavior. So what does that mean?
Here is how 'undefined behavior' is defined :) in the Standard.
Permissible undefined behavior ranges
from ignoring the situation completely
with unpredictable results, to
behaving during translation or program
execution in a documented manner
characteristic of the environment
(with or without the issuance of a
diagnostic message), to terminating a
translation or execution (with the
issuance of a diagnostic message).
Many erroneous program constructs do
not engender undefined behavior; they
are required to be diagnosed.
Do you see correlation with #DarkDust's response 'The compiler is even allowed to set your computer on fire :-)'
So any output you get from such a code is really in the dreaded realm of undefined behavior.
Don't do it.
Only thing that is defined about such code is that it helps OP and many of us get lots of votes (if answered correctly) :)
The result of the second program's expression is undefined. The compiler is even allowed to set your computer on fire :-) You're not allowed to modify a variable twice within one sequence point (in this case: from = to ;).
Edit:
For detailed explanations, see the C FAQ, specifically question 3.2.
Adding to other's answers:
If you are using g++, using the -Wsequence-point option tells that:
$ g++ -Wsequence-point a.cpp
a.cpp: In function ‘int main()’:
a.cpp:8: warning: operation on ‘i’ may be undefined
^^^^^^^^^
Undefined behaviour, so anything could happen
A friend tells me that after:
int C = anything;
C == C++ will have the value true. This is intended as a joke, a rebuttal of sorts to the oft-claimed "C is not the same as C++".
However, since == is not a sequence point, I argue that this is in fact undefined behavior. The program may first evaluate C++, so that C > C++ and C == C++ are both undefined. However, C >= C++ will always evaluate as true. The same, of course, is true when the operands are flipped (C++ <= C is always true and everything else is undefined).
Is this analysis correct?
All cases lead to undefined behavior and unpredictable results.
The draft C++11 standard tells us that unless stated otherwise the order of evaluations of operands are unsequenced and if the same scalar object is modified more that once by unseqeucend side effects than we have undefined behavior. It is also undefined if we need modify the object and have to compute the value of the object for another operand. This is covered in the draft C++11 standard section 1.9
Except where noted, evaluations of operands of individual operators
and of subexpressions of individual expressions are unsequenced. [
Note: In an expression that is evaluated more than once during the
execution of a program, unsequenced and indeterminately sequenced
evaluations of its subexpressions need not be performed consistently
in different evaluations. —end note ] The value computations of the
operands of an operator are sequenced before the value computation of
the result of the operator. If a side effect on a scalar object is
unsequenced relative to either another side effect on the same scalar
object or a value computation using the value of the same scalar
object, the behavior is undefined.
Neither the equality operators or relational operators in sections 5.9 Relational operators and 5.10 Equality operators specify a sequencing for the operands.
clang also provides a warning for this case, it looks like by default, it should something similar to the following (see it live):
warning: unsequenced modification and access to 'C' [-Wunsequenced]
if( C == C++ )
~ ^
This is also undefined behavior in C++03 with did not use the concept of sequencing relationships but just sequence points. In the draft C++03 standard the relevant section would be Chapter 5 Expressions which says:
Except where noted, the order of evaluation of operands of individual
operators and subexpressions of individual expressions, and the order
in which side effects take place, is unspecified.57) Between the
previous and next sequence point a scalar object shall have its stored
value modified at most once by the evaluation of an expression.
Furthermore, the prior value shall be accessed only to determine the
value to be stored. The requirements of this paragraph shall be met
for each allowable ordering of the subexpressions of a full
expression; otherwise the behavior is undefined.
which is simpler to reason about since multiple modification of or a modification and use of the value of a scalar within the same sequence point is undefined behavior without having to figure out the sequencing of operations.
You are correct. Even the compiler says so: compiling
#include <iostream>
int main()
{
int C = 0;
if (C == C++) {
...
results in:
main.cpp: In function 'int main()':
main.cpp:6:17: warning: operation on 'C' may be undefined [-Wsequence-point]
if (C == C++) {
^
(Coliru)
This question already has answers here:
Why are these constructs using pre and post-increment undefined behavior?
(14 answers)
Closed 8 years ago.
#include <iostream>
using namespace std;
main(){
int i = 5;
cout << i++ << i--<< ++i << --i << i << endl;
}
The above program compiled with g++ gives output :
45555
While the following program:
int x=20,y=35;
x =y++ + y + x++ + y++;
cout << x<< endl << y;
gives result as
126
37
Can anyone please explain the output.
cout << i++ << i--
is semantically equivalent to
operator<<(operator<<(cout, i++), i--);
<------arg1--------->, <-arg2->
$1.9/15- "When calling a function
(whether or not the function is
inline), every value computation and
side effect associated with any
argument expression, or with the
postfix expression designating the
called function, is sequenced before
execution of every expression or
statement in the body of the called
function. [ Note: Value computations
and side effects associated with
different argument expressions are
unsequenced. —end note ]
C++0x:
This means that the evaluation of the arguments arg1/arg2 are unsequenced (neither of them is sequenced before the other).
The same section in the draft Standard also states,
If a side effect on a scalar object is
unsequenced relative to either another
side effect on the same scalar object
or a value computation using the value
of the same scalar object, the
behavior is undefined.
Now there is a sequence point at the semicolon at the end of the full expression below
operator<<(operator<<(cout, i++), i--);
^ the interesting sequence point is right here
As is clear, evaluation of both arg1 and arg2 lead to side effect on the scalar variable 'i', and as we saw above, the side effects are unsequenced.
Therefore the code has undefined behavior. So what does that mean?
Here is how 'undefined behavior' is defined :) in the Standard.
Permissible undefined behavior ranges
from ignoring the situation completely
with unpredictable results, to
behaving during translation or program
execution in a documented manner
characteristic of the environment
(with or without the issuance of a
diagnostic message), to terminating a
translation or execution (with the
issuance of a diagnostic message).
Many erroneous program constructs do
not engender undefined behavior; they
are required to be diagnosed.
Do you see correlation with #DarkDust's response 'The compiler is even allowed to set your computer on fire :-)'
So any output you get from such a code is really in the dreaded realm of undefined behavior.
Don't do it.
Only thing that is defined about such code is that it helps OP and many of us get lots of votes (if answered correctly) :)
The result of the second program's expression is undefined. The compiler is even allowed to set your computer on fire :-) You're not allowed to modify a variable twice within one sequence point (in this case: from = to ;).
Edit:
For detailed explanations, see the C FAQ, specifically question 3.2.
Adding to other's answers:
If you are using g++, using the -Wsequence-point option tells that:
$ g++ -Wsequence-point a.cpp
a.cpp: In function ‘int main()’:
a.cpp:8: warning: operation on ‘i’ may be undefined
^^^^^^^^^
Undefined behaviour, so anything could happen