Expressions
From:     http://www.lysator.liu.se/c/c-faq/c-4.html




Section 4. Expressions

4.1: Why doesn't this code:

	a[i] = i++;

work?

The subexpression i++ causes a side effect -- it modifies i's value --
which
leads to undefined behavior if i is also referenced elsewhere in the same
expression.  (Note that although the language in K&R suggests that the
behavior of this expression is unspecified, the ANSI/ISO C Standard makes
the stronger statement that it is undefined -- see question 5.23.)

References: ANSI Sec. 3.3 p. 39.

4.2: Under my compiler, the code

	int i = 7;
	printf("%d\n", i++ * i++);

prints 49.  Regardless of the order of evaluation, shouldn't it print 56?

Although the postincrement and postdecrement operators ++ and -- perform
the
operations after yielding the former value, the implication of "after" is
often misunderstood.  It is not guaranteed that the operation is performed
immediately after giving up the previous value and before any other part of
the expression is evaluated.  It is merely guaranteed that the update will
be performed sometime before the expression is considered "finished"
(before
the next "sequence point," in ANSI C's terminology).  In the example, the
compiler chose to multiply the previous value by itself and to perform both
increments afterwards.

The behavior of code which contains multiple, ambiguous side effects has
always been undefined (see question 5.23).  Don't even try to find out how
your compiler implements such things (contrary to the ill-advised exercises
in many C textbooks); as K&R wisely point out, "if you don't know how they
are done on various machines, that innocence may help to protect you."

References: K&R I Sec. 2.12 p. 50; K&R II Sec. 2.12 p. 54; ANSI Sec. 3.3 p.
39; CT&P Sec. 3.7 p. 47; PCS Sec. 9.5 pp. 120-1. (Ignore H&S Sec. 7.12 pp.
190-1, which is obsolete.)

4.3: I've experimented with the code

              int i = 2;
              i = i++;

on several compilers.  Some gave i the value 2, some gave 3, but one gave
4.
 I know the behavior is undefined, but how could it give 4?

Undefined behavior means anything can happen.  See question 5.23.

4.4: People keep saying the behavior is undefined, but I just tried it on
an
ANSI-conforming compiler, and got the results I expected.

A compiler may do anything it likes when faced with undefined behavior
(and,
within limits, with implementation-defined and unspecified behavior),
including doing what you expect.  It's unwise to depend on it, though.  See
also question 5.18.

4.5: Can I use explicit parentheses to force the order of evaluation I
want?
 Even if I don't, doesn't precedence dictate it?

Operator precedence and explicit parentheses impose only a partial ordering
on the evaluation of an expression. Consider the expression

             f() + g() * h()

-- although we know that the multiplication will happen before the
addition,
there is no telling which of the three functions will be called first.

4.6: But what about the &&, ||, and comma operators? I see code like "if((c
= getchar()) == EOF || c == '\n')" ...

There is a special exception for those operators, (as well as the ?:
operator); each of them does imply a sequence point (i.e. left-to-right
evaluation is guaranteed).  Any book on C should make this clear.

References: K&R I Sec. 2.6 p. 38, Secs. A7.11-12 pp. 190-1; K&R II Sec. 2.6
p. 41, Secs. A7.14-15 pp. 207-8; ANSI Secs. 3.3.13 p. 52, 3.3.14 p. 52,
3.3.15 p. 53, 3.3.17 p. 55, CT&P Sec. 3.7 pp. 46-7.

4.7: If I'm not using the value of the expression, should I use i++ or ++i
to increment a variable?

Since the two forms differ only in the value yielded, they are entirely
equivalent when only their side effect is needed.

4.8: Why doesn't the code

	int a = 1000, b = 1000;
	long int c = a * b;

work?

Under C's integral promotion rules, the multiplication is carried out using
int arithmetic, and the result may overflow and/or be truncated before
being
assigned to the long int left- hand-side.  Use an explicit cast to force
long arithmetic:

	long int c = (long int)a * b;

Note that the code (long int)(a * b) would not have the desired effect.