2
#include <stdio.h>
void main()
{
int x=5,y=6;
printf("%d%d%d",x++,(y=x++),(x=y++));
}

Can anyone please explain why does this returns 766?

killer007
  • 78
  • 6
  • 3
    `void main()` is not the correct signature for the entry point of a C program. What value were you *expecting* to receive? – Cody Gray - on strike Feb 02 '12 at 06:00
  • OMG questions like this one must forbidden on SO. – qrdl Feb 02 '12 at 06:02
  • 2
    @qrdl - well we weren't all born as 'C' masters. – Martin Beckett Feb 02 '12 at 06:05
  • 1
    well actually it's a question form the last semester exam of my university..and after 30 minutes of head banging i still cant understand why it returns 766...That is why i am asking on SO – killer007 Feb 02 '12 at 06:09
  • 3
    @killer007, then either you missed the point where your teacher was introducing undefined behavior, or (much worse) your teacher was pretending that this program should have a deterministic result. The incorrect signature for `main` makes me fear that you are confronted with the later. – Jens Gustedt Feb 02 '12 at 07:33
  • Another option, as unthinkable as it is, may be that the teacher doesn't have a clue about undefined behavior. – Lundin Feb 02 '12 at 09:40
  • 2
    @Lundin: given that `main` is typed `void`, it seems pretty likely that the teacher doesn't have a clue about a lot of things. Let's face it, C is almost universally taught badly. A *lot* of wrong information and bad practice has been institutionalized over the years thanks to authors like Schildt, and it's infested the teaching level. And no, I don't have a clue about how to address it, other than to come here and try my best to help correct those misunderstandings. – John Bode Feb 02 '12 at 12:04
  • possible duplicate of [Why are these constructs undefined behavior?](http://stackoverflow.com/questions/949433/why-are-these-constructs-undefined-behavior) – Kevin Feb 07 '14 at 15:44

7 Answers7

9

First, if this question, in this format, was given on a beginner C programming course, the course/teacher is a bad one.

The main problem here is that both 'x' and 'y' are modified several times before a sequence point, which is undefined behavior (C99/C11 6.5 §2). This is a severe bug, because anything can happen. Before the ++ mess is removed, there is no telling what this code does. Read this then read it again.

Further, the order of evaluation of function arguments is unspecified behavior. (C99/C11 6.5.2.2 §10). That is, the compiler may evaluate them left-to-right or right-to-left, and we cannot know which order that applies. The compiler does not need to document this! But if you are lucky, it could be documented. You must then read the compiler documentation to see which order of evaluation that applies, before attempting to answer the question. Otherwise you must give two answers.

Further, if this is code for a hosted system, such as a Windows PC, main is only allowed to return 'int' or this code won't compile on a C compiler.

Community
  • 1
  • 1
Lundin
  • 195,001
  • 40
  • 254
  • 396
3

You've invoked undefined behavior by modifying x more than once between sequence points, so you're lucky/unlucky it printed anything at all...

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
2

Yes, it's undefined what order the arguements to a function like this are parsed in.

The easiest way to handle a variable number of args function like printf is to start from the end, since you know where the beginning is!

As 'R' points out - it's undefined to have a statement where the evaluation is ambiguous. eg x++ = x++

Martin Beckett
  • 94,801
  • 28
  • 188
  • 263
  • Not just the order is undefined. The **behavior** is undefined. There is no sequence point between the modifications of `x`. – R.. GitHub STOP HELPING ICE Feb 02 '12 at 06:01
  • The order of argument evaluation of a function is _unspecified behavior_, ie the compiler need not document in which order it evaluates them, but it must do so in a safe and deterministic manner (right-to-left or left-to-right). However, in this example 'i' is also modified twice before a sequence point, and that is undefined behavior. – Lundin Feb 02 '12 at 09:12
  • @Lundin : variable "i" in the example? Where? – dicaprio Feb 02 '12 at 10:35
  • Sorry, x. And y too for that matter. – Lundin Feb 02 '12 at 11:52
0

This working stack concept as the mention operation LIFO firt right operand goes to the stack that is x = y++ (this is the post increament opratore then first y value assing to x after y will increament that is x=6 )then secound (here x = 6 and y = 7 but y is assign value of x that is 6 then x will increament by 1)and third (here x=7 and after this statement x will increament by 1 ) hance the values are 766.

-1

it first evaluates the last expression (x=y++). This will return 6 because x is assigned with the value of y which is 6 initially and then it increments y to 1. Now y is 7 and x is 6. x is printed here.

next expression to be evaluated is (y=x++). Same as above first assign y= x and increment x to 1. So the values are y is 6 and x is 7. y is printed here.

now x++. it prints 7 and increments x to 1.

Jayy
  • 2,368
  • 4
  • 24
  • 35
  • Thanks for the wonderful explanation . Now I understand it :) – killer007 Feb 02 '12 at 06:13
  • 1
    @killer007, no you don't understand it with this answer. This answer gives you the impression that there is something deterministic going on, which might be true for a particular compiler, but is completely wrong in general. First as R indicates in his answer, modifying variables in that way is undefined behavior, anything can happen. Then even if you wouldn't modify the variables the evaluation order is unspecific, there are compilers that evaluate from left to right, others do the invers. – Jens Gustedt Feb 02 '12 at 07:29
  • @JensGustedt: Yes i agree. this might be true for a particular compiler, but is completely wrong in general. I know some compliers evalute left to right and others inverse. I explained him why his compiler returned 766. The answer is just the logic part. – Jayy Feb 02 '12 at 09:28
  • The order of evaluation of function arguments is unspecified behavior. Modifying a variable twice before a sequence point is undefined behavior. There is no way to tell the result of that code. – Lundin Feb 02 '12 at 09:36
  • @Lundin: I read your [link](http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points), I agree your point. – Jayy Feb 02 '12 at 11:21
-2

excecution strts frm right to left.So,x=y++,x value becomes 6 and after that y value become seven followed by y=x++,which restoe value of y to 6.After that in x++ statement x value is 7 due to the previous statement(y=x++).And so is the answer 766

pratik
  • 1
-3
printf("%d%d%d",x++,(y=x++),(x=y++)); 

Wanted to add why it's evaluated from the right end as previous answers mentioned. All the arguments of printf are pushed to a stack and then evaluation begins. As stack is LIFO, evaluation begins from the end.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
Thunderman
  • 115
  • 1
  • 5
  • 1
    The order of evaluation of function arguments is unspecified behavior. Modifying a variable twice before a sequence point is undefined behavior. There is no way to tell the result of that code. – Lundin Feb 02 '12 at 09:13