printf() problem

Doug Gwyn gwyn at smoke.BRL.MIL
Thu Apr 27 15:14:30 AEST 1989


In article <353 at secola.Columbia.NCR.COM> gharris at secola.Columbia.NCR.COM (Buddy Harris) writes:
>This is something that I don't understand either, but apparently 
>printf() evluates from right to left.  Be careful with stetements like this:
>     printf("%d %d %d %d", i++, i++, i++, i++);
>This evluates from right to left also.  

Despite there having been several correct (and several incorrect)
postings about this already, I think it is important to understand
exactly what is going on here.

It is not the case that printf() is evaluating its arguments.  The
compiler generates code that evaluates the arguments BEFORE the call
is made to the printf() function.  There are several contexts in C
where the exact order of evaluation is deliberately not specified by
the language, leaving it up to the implementation (i.e. compiler) to
select whatever is most efficient or most convenient.  It would have
been possible in principle for the C language specification to have
included a requirement that function arguments be evaluated in a
certain order; indeed, first-to-last, i.e. left-to-right in our
culture, would have been the natural order to specify.  Why, then,
was this left unspecified?

The answer has to do with the details of implementing function-call
linkage.  Briefly, machine architectures vary widely.  It may well
happen, as it does on many modern stack-based architectures, that
the most efficient way to implement function linkage involves pushing
the last (rightmost) argument datum onto the hardware stack first, so
that the first function parameter is the one nearest the top of the
stack.  This is to some extent influenced by the existence of variadic
functions such as printf().  For other architectures (typically non
stack-based ones), it may be more efficient to store the first
(leftmost) argument datum first.  In order to allow implementations
the flexibility to select the fastest method for function linkage, C
does not require either choice, and this is reflected in the
unspecified order of argument evaluation.

By the way, it is easy to give incorrect arguments based on whether
stacks most naturally grow upward or downward on the architecture.
Lacking some requirement for function parameters having to be in a
particular address order (which I was unable to come up with), the
"natural" direction of stack growth isn't really a factor.



More information about the Comp.lang.c mailing list