By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
428,558 Members | 1,603 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 428,558 IT Pros & Developers. It's quick & easy.

Knowing your sequence points

P: n/a
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

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.
August

(I would never write this kind of code in practice, but it's good to
know how the standard is defined.)
Nov 15 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
akarl wrote:

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

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.


That's not what left associative means.

--
pete
Nov 15 '05 #2

P: n/a
pete wrote:
akarl wrote:
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

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.

That's not what left associative means.


Yes, of course (only one addition operation). How stupid of me. So the
ambiguity here is that the *evaluation order* of the operands of `+' is
unspecified, right?

August
Nov 15 '05 #3

P: n/a
On Thu, 11 Aug 2005 02:15:14 GMT, akarl <fu********@comhem.se> wrote
in comp.lang.c:
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
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.
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.
No, you are wrong, associatively has nothing at all to do with order
of evaluation. Only sequence points impose an order of evaluation.
August

(I would never write this kind of code in practice, but it's good to
know how the standard is defined.)


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

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
Nov 15 '05 #4

P: n/a
akarl wrote:

pete wrote:
akarl wrote:
printf("%i\n", f(n++) + n); test.c:13: warning: operation on ‘n’ may be undefined `f(n++)' which is evaluated before
`n' since addition is left associative.
I can't see the ambiguity here.

That's not what left associative means.


Yes, of course (only one addition operation). How stupid of me. So the
ambiguity here is that the *evaluation order*
of the operands of `+' is unspecified, right?


Yes. There are rules that say that modifying n
and reading n between sequence points, is undefined,
even though it might seem to be only unspecified.

I think it's good to avoid side effects in function arguments.
I absentmindedly used an argument with side effects in the
Re: A question on string literals
thread, thereby confusing Default User.
It would have been more better if I had
incremented the pointer prior to the function call
instead of in the function call.

--
pete
Nov 15 '05 #5

P: n/a
akarl wrote:
Hi all,

Why do I get a warning from gcc with the following program? [...] printf("%i\n", f(n++) + n); [...] test.c:13: warning: operation on ‘n’ may be undefined
Because the the value of 'f(n++) + n' is undefined.
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.


The order of evaluation of the operands f(n++) and n is not defined.
Associativity (which isn't a C concept, anyway) doesn't enter into it.
Nov 15 '05 #6

P: n/a

Jack Klein wrote:
On Thu, 11 Aug 2005 02:15:14 GMT, akarl <fu********@comhem.se> wrote
in comp.lang.c:
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
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.
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.


No, you are wrong, associatively has nothing at all to do with order
of evaluation. Only sequence points impose an order of evaluation.
August

(I would never write this kind of code in practice, but it's good to
know how the standard is defined.)


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


<nitpick>
or more likely:
function 1
function 1
the sum is 3
</nitpick>
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


Nov 15 '05 #7

P: n/a
On 10 Aug 2005 23:55:56 -0700, "Suman" <sk*****@gmail.com> wrote in
comp.lang.c:
Jack Klein wrote:


[snip]
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


<nitpick>
or more likely:
function 1
function 1
the sum is 3
</nitpick>


Kind of takes the away the whole point of the example, doesn't it?
Makes it really, really indeterminate!

Thanks, Suman, nice catch.

--
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
Nov 15 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.