Jack Klein wrote:[color=blue]
> On Thu, 11 Aug 2005 02:15:14 GMT, akarl <fusionfive@comhem.se> wrote
> in comp.lang.c:
>[color=green]
> > Hi all,
> >
> > Why do I get a warning from gcc with the following program?
> >
> > [test]$ cat test.c
> > #include <stdio.h>
> >
> > int f(int n)
> > {
> > return n;
> > }
> >
> >
> > int main(void)
> > {
> > int n = 0;
> >
> > printf("%i\n", f(n++) + n);
> > return 0;
> > }
> >
> > [test]$ gcc -Wall test.c
> > test.c: In function 'main':
> > test.c:13: warning: operation on 'n' may be undefined[/color]
>
> Yes, the operation on 'n' may be undefined. The standard says:
>
> "Between the previous and next sequence point an object shall have its
> stored value modified at most once by the evaluation of an expression.
> Furthermore, the prior value shall be read only to determine the value
> to be stored."
>
> The printf() call in your call does not modify the value of 'n' more
> than once. The expression 'n++' modifies 'n' exactly once, and uses
> the original value of 'n' only for the purpose of computing the new
> value. But the '+ n' subexpression attempts to access the prior value
> of 'n' in a way that is not used in the computation of the new value.
>[color=green]
> > One of the sequence point cases is defined as: "The point of calling a
> > function, after evaluating its arguments." If I got it right, that rule
> > can be applied to `f(n++)' which is evaluated before `n' since addition
> > is left associative. I can't see the ambiguity here.[/color]
>
> No, you are wrong, associatively has nothing at all to do with order
> of evaluation. Only sequence points impose an order of evaluation.
>[color=green]
> > August
> >
> > (I would never write this kind of code in practice, but it's good to
> > know how the standard is defined.)[/color]
>
> Let's take an example that doesn't have undefined behavior:
>
> #include <stdio.h>
>
> int f1(void)
> {
> puts("function 1\n");
> return 1;
> }
>
> int f2(void)
> {
> puts("function 1\n");
> return 2;
> }
>
> int main(void)
> {
> printf("the sum is %d\n", f1() + f2());
> return 0;
> }
>
> This function does not define or contain any objects at all, so the
> paragraph I quoted from the standard certainly does not apply.
>
> Because the order of evaluation between sequence points is
> unspecified, the output could be either of the following two
> sequences, and must be one of the two:
>
> function 1
> function 2
> the sum is 3
>
> ...or:
>
> function 2
> function 1
> the sum is 3[/color]
<nitpick>
or more likely:
function 1
function 1
the sum is 3
</nitpick>
[color=blue]
> In fact, it may change between one and the other if you change the
> settings you use to invoke your compiler, for example enable or
> disable optimization.
>
> If just so happens that if your compiler evaluates the subexpression
> 'f(n++)' first, the result is defined because there is a sequence
> point imposed by calling the function before the '+ n' subexpression
> reads the value of 'n' again.
>
> But if your compiler evaluates 'n' in the '+ n' subexpression before
> evaluating the 'f(n++)' subexpression, there is no sequence point
> between the unrelated read and the modification, the behavior is
> undefined.
>
> Finally, since the order of evaluation is something the standard
> states is unspecified, it means that the compiler does not have to
> tell you which order it uses, and is free to change it based on
> settings, the day of the week, or the phase of the moon.
>
> Since one of the unspecified paths generates undefined behavior, the
> whole thing should be treated as undefined.
>
> --
> Jack Klein
> Home:
http://JK-Technology.Com
> FAQs for
> comp.lang.c
http://www.eskimo.com/~scs/C-faq/top.html
> comp.lang.c++
http://www.parashift.com/c++-faq-lite/
> alt.comp.lang.learn.c-c++
>
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html[/color]