the order of printf parameter

M

marsarden

--------pq.c--------
#include <stdio.h>
void main()
{
int a=2,*p,*q;
p=&a;q=&a;
printf("%d %d\n",*p++,*(q++));
printf("%d\n",a);
p=&a;q=&a;
printf("%d %d\n",*p,(*q)++);
}
-----------------------------------------
in gcc it output:

2 2
2
3 2

in vc6 it output:
2 2
2
2 2

anyone can tell me how the printf works?
 
K

Keith Thompson

marsarden said:
--------pq.c--------
#include <stdio.h>
void main()

Find yourself a chalkboard and a piece of chalk (a whiteboard and a
marker will do if necessary). Write 100 times:
"main() returns int."

Change the line to "int main(void)".
{
int a=2,*p,*q;
p=&a;q=&a;

Ok, p and q both point to a, which has the value 2.
printf("%d %d\n",*p++,*(q++));

This should always print "2 2". You increment both pointers after
dereferencing them, which is fairly pointless, but it's harmless.
printf("%d\n",a);

This will print "2".
p=&a;q=&a;

Now p and q both point to a again.
printf("%d %d\n",*p,(*q)++);

Here the third argument increments the object that q points to (namely a).

But as for any function call, the order of evaluation of the arguments
is unspecified.

Finally, since main() returns int, you should have a "return 0;" here.
}
-----------------------------------------
in gcc it output:

2 2
2
3 2

in vc6 it output:
2 2
2
2 2

Since the order of evaluation is unspecified, both results are valid.

If you care about the output, write the call so that it will work
properly and consistently regardless of the order of evaluation of the
arguments. For example, do the increment before or after the call,
not in the middle of it. If you keep your code simple and readable,
you don't have to *care* about details like this.
 
F

Flash Gordon

Keith said:
Now p and q both point to a again.


Here the third argument increments the object that q points to (namely a).

But as for any function call, the order of evaluation of the arguments
is unspecified.


Since the order of evaluation is unspecified, both results are valid.

It's worse than that surely? The value of a is being modified by (*q)++
and read for a purpose other than calculating the new value by *p with
no intervening sequence point, so surely this is undefined behaviour?

To the OP, undefined behaviour means that anything at all is valid, even
the program causing the HD in the computer to spin up to 10000000rpm and
then fly apart killing everyone in a 100 foot radius. Although in this
case the results you are seeing are more likely.
If you care about the output, write the call so that it will work
properly and consistently regardless of the order of evaluation of the
arguments. For example, do the increment before or after the call,
not in the middle of it. If you keep your code simple and readable,
you don't have to *care* about details like this.

Agreed.
 
O

Old Wolf

Keith said:
Ok, p and q both point to a, which has the value 2.


Here the third argument increments the object that q points to (namely a).

But as for any function call, the order of evaluation of the arguments
is unspecified.

Unfortunately, *p and *q are the same object. So, as
Flash (saviour of the universe) suggested, we definitiely
have UB: there is no sequence point between the write of *q,
and the read of *p.
 
K

Keith Thompson

Old Wolf said:
Unfortunately, *p and *q are the same object. So, as
Flash (saviour of the universe) suggested, we definitiely
have UB: there is no sequence point between the write of *q,
and the read of *p.

You're right, I missed that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top