Link to home
Start Free TrialLog in
Avatar of darpangoel
darpangoelFlag for United States of America

asked on

printf

can anyone explain how printf works. is it's output implementation dependent? and also kindly explain the output for the following code.
# include <stdio.h>
void main()
{
      int i=10;
      printf ("%d %d %d",i,++i,++i);
}
i got
12 12 11
i don't understand how it works. kindly help.
thanx.
ASKER CERTIFIED SOLUTION
Avatar of imladris
imladris
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Dexstar
Dexstar

darpangoel:

> can anyone explain how printf works. is it's output implementation dependent?

The page explains it best:
http://computer.howstuffworks.com/c2.htm

It has a section that covers printf exclusively...
 
> and also kindly explain the output for the following code.

imladris already covered it, so I'm not going to repeat it...  :)


Hope That Helps,
Dex*
Avatar of darpangoel

ASKER

but supposedly if you run the same code in vc .net the output is 12 12 12. how is it so?
(i haven't tried it on vc .net but thats what i was told.)
I'm not particularly certain why that program outputs 12, 12, 11, as I am a learning C coder myself, but I can explain a bit on printf.

The basic syntax of printf is:    printf("<formatted output>", var1, var2, var3, var4);
Some of the switches I use routinely for printf are %d (integer), %e (scientific notation), %f (double, floating point), %c (character), and %s (string of characters).

The C compiler will basically go from left to right matching matching up fields with the variable arguments you give.

For instance, printf("%d<>%e<>%c", 3, 345.6, 'c'); would ouput :  3<>3.456000e+002<> c

Hope that helps a little with the primary question.  I'm lost on finding an answer to the second one.
>>So, since i is 10, the first value pushed onto the stack will be 11 (10, preincremented), the second will be 12 (preincremented again), then 12 again, then the format specifier. And so it will print exactly what you saw: 12 12 11.

That makes perfect sense.  Thanks for the clear explanation imladris.
On VS.NET, you will get 12 12 12!

It has to do with how the compiler puts the variables onto the stack, and the order in which they are evaluated, so yes, it is compiler specific.

Dex*
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/expre_11.asp

"Function-call operator. All arguments to a function are evaluated and all side effects complete before entry to the function. No order of evaluation among the arguments is specified."

So, the order of evaluation of i, ++i and ++i is unspecified. The possible outcomes should be:

10, 11, 12 (1,2,3)
10, 12, 11 (1,3,2)
11, 11, 12 (2,1,3)
12, 11, 12 (2,3,1)
11, 12, 11 (3,1,2)
12, 12, 11 (3,2,1)

But not 12, 12, 12.

Imladris explained why 12, 12, 11 is the most likely order.
mtmike,

I compiled it on VS.NET 2002 and it gives you 12, 12, 12!  Try it yourself.

Dex*
If it prints out 12,12,12 then it looks like it is doing all the pre-increments first, then pushing the values.  
Doesnt sound right.  Weird.
I would assume that the VC.NET compiler is in fact a C++ compiler. It may be that there are different rules for C++.

Also, this kind of thing (referring to i multiple times, some of which are pre (or post) incremented and some not) is often compiler dependant (i.e. left to the compiler implementors for decisions). So it is unwise to ever code such things in real life.
I looked it up, and according to the C standard, the compiler's behaviour is undefined...  So don't write code that depends on those parameters being evaluated in a certain order.

Dex*