I am a novice programmer and need help.....
#include <stdio.h>
int main (void)
}
    int n1=2;
    int n2=0;
    n2= (++n1) + (++n1);
    printf("Result= %d",n2);
    return 0;
}
Result= 8      How is this possible??


Similarly, 
#include <stdio.h>
int main (void)
}
    int n1=2;
    int n2=0;
    n2= (++n1) + (++n1) + (++n1);
    printf"Result= %d",n2);
    return 0;
}

Result= 13              How is it possible??

All the results does not match up with my understanding of C. Please, I need help.
Thank you.

All the results does not match up with my understanding of C.

This is because you haven't yet learned the sequence point rule concerning modifications. The rule states that an object may be modified at most one time between sequence points, otherwise the result is undefined behavior. The + operator does not act as a sequence point, and ++ modifies the object.

So, in your first example you're modifying n1 twice between sequence points, and in your second example n1 is being modified thrice. Undefined behavior means that a compiler can do pretty much anything, so don't count on any kind of predictable result even on the same compiler. Technically, you could run this program twice and get different results.

@narue..I am also a C beginner...
I have ran this program on my compiler DEV C++.
I also get same result=8
I have compiled many times...and It shows same output...
So there is specific thing is going wrong...
Can you explain more about "sequence point rule"...or give some good reference?

I have ran this program on my compiler DEV C++.
I also get same result=8
I have compiled many times...and It shows same output...

The problem with undefined behavior is that it's 100% unpredictable. The results could be intuitive or not. The results could be consistent or not. It could run perfectly for a year, then blow up when you're demoing your program to someone who wants to buy it. It could blow up immediately, then magically start working when you try to troubleshoot.

The lesson here is do not invoke undefined behavior.

So there is specific thing is going wrong...

Yes. What's wrong is no longer bound by the rules of C++ and can behave however the author of the compiler chose to handle such expressions, or if the author did not explicitly handle such expressions, whatever behavior falls out of the compiler's expression logic.

Can you explain more about "sequence point rule"...or give some good reference?

http://en.wikipedia.org/wiki/Sequence_point

This is because you haven't yet learned the sequence point rule concerning modifications. The rule states that an object may be modified at most one time between sequence points, otherwise the result is undefined behavior. The + operator does not act as a sequence point, and ++ modifies the object.

So, in your first example you're modifying n1 twice between sequence points, and in your second example n1 is being modified thrice. Undefined behavior means that a compiler can do pretty much anything, so don't count on any kind of predictable result even on the same compiler. Technically, you could run this program twice and get different results.


I have been following a book named "Let Us C" by Yashavant Kanetkar. I can't find out the topic "Sequence Point Rule" in here. It must be the reason why I have not been able to understand it. Thank you for the help.

I have been following a book named "Let Us C" by Yashavant Kanetkar.

I haven't heard good things about that particular book.

I can't find out the topic "Sequence Point Rule" in here.

That's because your book is for beginners and sequence points are a concept that isn't strictly necessary when first learning the language.

I haven't heard good things about that particular book.


That's because your book is for beginners and sequence points are a concept that isn't strictly necessary when first learning the language.

Well its the book recommended by my teacher. Now I think that I have to consult other books. Thanks for the info.....

Well its the book recommended by my teacher. Now I think that I have to consult other books. Thanks for the info.....

Is the book called "ANSI C" by E. Balagurusamy informative?

Is the book called "ANSI C" by E. Balagurusamy informative?

It's a gross generalization, but in my experience, if the publisher is out of India, it raises red flags; I have yet to see a decent beginner's book on programming come out of India. Can you learn from these books? Absolutely. Will you pick up an excessive number of bad habits along the way? Very likely.

Go here and find a book that's either recommended or highly recommended.

It's a gross generalization, but in my experience, if the publisher is out of India, it raises red flags; I have yet to see a decent beginner's book on programming come out of India. Can you learn from these books? Absolutely. Will you pick up an excessive number of bad habits along the way? Very likely.

Go here and find a book that's either recommended or highly recommended.

Isn't that like kind of general? Thats a huge list of books, and it seems to me like the majority of them are C++ oriented, not C oriented. In my opinion, "The C Programming Language" by Brain Kernighan and Dennis Ritchie is probably one of the best books on ANSI C.

Isn't that like kind of general?

Yes, generalizations tend to be kind of general. :icon_rolleyes:

Isn't that like kind of general? Thats a huge list of books, and it seems to me like the majority of them are C++ oriented, not C oriented. In my opinion, "The C Programming Language" by Brain Kernighan and Dennis Ritchie is probably one of the best books on ANSI C.

Thanx chrjs I just googled about "The C Programming Language" and will stick to it . Here http://accu.org/index.php?module=bookreviews&func=browse almost every book is related to either .NET, Java or C++. I just need a book which deals with "C" that way it will help me make a solid foundation for my programming knowledge. Narue, thanx for the "link" as well as "suggestion" though.

almost every book is related to either .NET, Java or C++

They have books on C too. The search is godawful though, which is why I linked you to the browse page. But if it's too hard to scroll and search for C, I'm sorry.

Narue, thanx for the "link" as well as "suggestion" though.

...

While the previous responses tell you why not to expect the answer you were expecting (I guess 7 in the first case, and 12 in the second case), no one has explained what actually happened. In the first case, the compiler has to generate code to add 2 operands, which are in fact at the same memory address. However, before it can do the addition, it has been asked to first increment those operands, which in the general case, it must do before the addition. This means that n1 is incremented twice (to equal 4) so when the addition is performed, you get 8. In the second case, the result of the first addition is stored in a temporary, then n1 is incremented to equal 5 and then added to the temporary (8+5=13).

This in no way contradicts the comments about sequencing. Another compiler implementation may increment and copy to a temp, then increment and add, giving the result you expect - in both cases. However, the implementation could also do all 3 increments in the second case, then add, giving 15. The particular implementation chosen may even vary in the same compiler depending upon what other code is in the neighbourhood. Hence, the result is not defined.

Edited 5 Years Ago by sbesch: Changed reference to n1 from n2

While the previous responses tell you why not to expect the answer you were expecting (I guess 7 in the first case, and 12 in the second case), no one has explained what actually happened. In the first case, the compiler has to generate code to add 2 operands, which are in fact at the same memory address. However, before it can do the addition, it has been asked to first increment those operands, which in the general case, it must do before the addition. This means that n1 is incremented twice (to equal 4) so when the addition is performed, you get 8. In the second case, the result of the first addition is stored in a temporary, then n1 is incremented to equal 5 and then added to the temporary (8+5=13).

This in no way contradicts the comments about sequencing. Another compiler implementation may increment and copy to a temp, then increment and add, giving the result you expect - in both cases. However, the implementation could also do all 3 increments in the second case, then add, giving 15. The particular implementation chosen may even vary in the same compiler depending upon what other code is in the neighbourhood. Hence, the result is not defined.

Now I'm getting really confused......... Which one to accept?? Sequencing problem as explained by Narue or other factor as explained by sbesch?

Which one to accept?? Sequencing problem as explained by Narue or other factor as explained by sbesch?

Both are acceptable. You can think of it as the abstract vs. the concrete. My abstract view based on the C standard's rules says that your program is undefined and need not behave predictably. sbesch's concrete view based on enlightened speculation speculates how the compiler may be reaching the unintuitive result.

Don't panic...i am back to help you all...
n2=(++n1)+(++n1)
See the concept is that ++n1 is preincrement operator having greater priority so it will first increment n1 value and making it 3.....
n2=(++n1)+(++n1)
++n1 is preincrement operator so it will be incremented to 4....
Now the above code is similar as...
n2=4+4;
resulting 8 as answer....

In the next statement it is similar....and the output is 15 not 13 as you mentioned....

Don't panic...i am back to help you all...
n2=(++n1)+(++n1)
See the concept is that ++n1 is preincrement operator having greater priority so it will first increment n1 value and making it 3.....
n2=(++n1)+(++n1)
++n1 is preincrement operator so it will be incremented to 4....
Now the above code is similar as...
n2=4+4;
resulting 8 as answer....

In the next statement it is similar....and the output is 15 not 13 as you mentioned....

*sigh*

I recognize that the concept of undefined behavior is somewhat confusing, especially when modern languages don't lean on undefined behavior nearly as much as C and C++. But just because you can come up with one viable way to interpret the expression doesn't mean that's the only way. The very reason it's undefined is because there are multiple equally good ways to evaluate the expression, and the standards committee didn't want to lock compilers into one method when another might be more efficient on the target platform.

You see certain syntactical expressions have a higher level of precedence than others By this I mean certain codes are "more important and so are executed first...for example ++ has a higher level of precedence that just + and brackets,namely () have an even higher order of precedence than ++ so the code below is saying

int n1=2;
int n2=0;
n2= (++n1) + (++n1);

(reading from right to left; the same in this instance vice versa), increment n1(n1 everywhere in the program is equal to 2+1 which is 3..but brackets has a higher level of precedence than the + so n1 is incremented again, thus becoming 3+1=4 everywhere in the program...You now have simply 4+4 which is eight..Makes sense?

Edited 5 Years Ago by CoilFyzx: I wanted to delete this because I read the thread and I realize a similar answer was there

You see certain syntactical expressions have a higher level of precedence than others By this I mean certain codes are "more important and so are executed first...for example ++ has a higher level of precedence that just + and brackets,namely () have an even higher order of precedence than ++ so the code below is saying

int n1=2;
int n2=0;
n2= (++n1) + (++n1);

(reading from right to left; the same in this instance vice versa), increment n1(n1 everywhere in the program is equal to 2+1 which is 3..but brackets has a higher level of precedence than the + so n1 is incremented again, thus becoming 3+1=4 everywhere in the program...You now have simply 4+4 which is eight..Makes sense?

No. First of all, as a professional programmer, even I was confused by your description in the upper half of your post.

And in the lower half, there is no guarantee you are correct because n2= (++n1) + (++n1); invokes undefined behavior, as Narue tried to point out. See this.

So, you can't tell if the answer should be 6, 7, or 8.

WaltP-I think so you need to study more ,understand the difference between preincrement and postincrement....
The link you gave is only for postincrement....
Better you must read it properly....

Better you must read it properly....

Better you reread the thread because you don't seem to understand the clear explanation that Narue was giving about undefined behavior.

Comments
counter.
Ohh i think you need to rereas

WaltP-I think so you need to study more ,understand the difference between preincrement and postincrement....
The link you gave is only for postincrement....
Better you must read it properly....

Really? Please explain exactly what and were my mistake was. Please go through that link I gave point by point and explain where I am wrong.

Edited 5 Years Ago by WaltP: n/a

I think so first of all you must understand the difference between preincrement and postincrement operator...
++i is called preincrement operator in which value is first incremented and then actions are performed whereas ++i is postincremented operator in which first operations are performed and then value is incremented....

No. First of all, as a professional programmer, even I was confused by your description in the upper half of your post.

See,not only you are professional...i m too professional....i came across such mistakes when i was in school and i found the solution to these problems...
By the way

The lesson here is do not invoke undefined behavior.

This is only the way to run from the problem rather than finding solution to the problem....
Undefined problem means it should give arbitrary answer but it is given correct answer.....So think once more about it...

Edited 5 Years Ago by tomato.pgn: n/a

Comments
Nice, arguing about pre- vs. post- and both examples are pre-

I think so first of all you must understand the difference between preincrement and postincrement operator...

That's really quite irrelevant. Both invoke undefined behavior when modifying an object multiple times between sequence points, in any combination.

This is only the way to run from the problem rather than finding solution to the problem....

There is no solution to the problem aside from avoiding it in the first place.

Comments
Unwarranted and undeserved
Explain it with explanation where it gave arbitrary result to proof your words

There is no solution to the problem aside from avoiding it in the first place.

Just don't know why you guys don't accept the way it is designed for and just tell it undefined sequence....:D
Just quote me one example when ++i gave two different output.....just cannot be defined...then i will accept that they show undefined sequence...

Just don't know why you guys don't accept the way it is designed for and just tell it undefined sequence....

We do accept the way it is designed: undefined, don't do it.

Just quote me one example when ++i gave two different output.....

You gave such an example in this very thread. And I quote:

In the next statement it is similar....and the output is 15 not 13 as you mentioned....

You say the output is 15 (presumably by testing it on your compiler), but the OP got a result of 13 on his compiler. If the result were well-defined then both compilers would agree, and print the same result.

Thank you all.....

I've got many answers and many confusions at the same time. I will clear out the confusions myself. Thanx for the reply and answers though.

You say the output is 15 (presumably by testing it on your compiler), but the OP got a result of 13 on his compiler. If the result were well-defined then both compilers would agree, and print the same result.

The answer he mentioned might beby mistake he typed wrong...just you check in your machine and many other machines and tell whether their is different in answer..?????
I have worked it out in over different platforms and machines and this is what i m getiing as an answer.....

This question has already been answered. Start a new discussion instead.