Re: C Test Incorrectly Uses printf() - Please Confirm



On Aug 9, 9:39 pm, Eric Sosman <esos...@xxxxxxxxxxxxxxxxxxxx> wrote:
On 8/9/2010 8:28 AM, Tom St Denis wrote:





On Aug 8, 4:07 pm, Willem<wil...@xxxxxxxxxxxxxxx>  wrote:
Shao Miller wrote:

) As in, the second argument has a definite value at least by the time of
) the function call.  So does the third argument have a value.  It doesn't
) matter whether the third argument's value is 6 or 7, because the format
) string doesn't use it.  Thus '2' is printed.

It's undefined behaviour.  Anything can happen.
'2' is not *guaranteed*.

I agree, it's extremely unlikely to be anything else.
Probably no system exists where it would not print 2.
But pedantically speaking, the result *is* undefined.

Well it's defined in the sense that logically one of two computations
can happen

     Right.  The two possibilities are "something unexpected" and
"everything else."

     "Undefined" means *undefined,* as in *not defined,* as in
*not defined at all, not limited or constrained in any way.*  The
Standard washes its hands to the point of sterility, it walks away
to an infinite distance in zero time, and you are On Your Own.  No
guarantees, no promises, no recourse, no no no no no.

All I read that as is the value of 'a + 5' is not defined. All the
work up to that point IS defined. computing an expression like 'a +
5' can have no side effects in this application since it's either 6 or
7 which are both valid 'int' values [no overflow].

I get what you're saying that since the ENTIRE statement is not
composed of defined expressions it's rejected as UB, but if we speak
practically for a second, it's a throwaway statement that can't have
side effects [other than taking time to compute].

In fact, since it's not even printed out it could just optimize out
the expression altogether.

I would therefore expect with every C compiler on this planet in
common use that the statement would print '2' as its output with
absolutely no undefined behaviour whatsoever. More so, I think this
is just a whole in the spec in which you have UB but it could be
defined [or at least mitigated] with a bit of logical deduction.

But finally, I do agree that it's a bad thing to do since in general
it could lead to UB with side effects, e.g.

int a[4], *p = &a[0];
a[1] = 4;
printf("%d\n", *++p, *(p + 3));

For instance might safely print '4' or it might crash with a bus error
[or whatever UB you can imagine].

Compare that to say

printf("%d\n", *++p, p == &a[0] ? 1 : 0);

This program will always print '4' on any C platform.

Tom
.