Muhtasim Fuad Showmik Muhtasim Fuad Showmik - 1 month ago 5
C Question

Does the expression a=(a++)*(++b) for a=3 and b=2 has any right or most acceptable answer? If so which is it?

Please help! I'm in trouble. This question was given to me in college and the teacher barely explained anything. It made sense to me that the answer would be 10 considering the original value of a being 3 is multiplied with b's incremented value 3 and then after executing the expression the value 9 is assigned to a. The post increment then later increases its value to 10.

The teacher blatantly said I'm simply wrong. No explanation whatsoever. He just said the a won't be incremented here.

Now I've checked several websites to investigate on the issue. I've learned cases such as i=i++ or a=a++ are undefined and should be avoided at all costs. But when it's provided in a test at college and then marks are in the process of being lost I didn't really have an option to avoid it and get past it.

While surfing through the internet I came across this website that shows different values under different compilers:
http://gynvael.coldwind.pl/?id=372

Now here's my question once again. Is there really any right answer at all? I understand most compilers would ultimately show 9 as a result because of the stack replacement process that happens (taught by Google but not the college I'm in) and I also understand that in some cases the compiler would follow the course of my logic which makes more sense to me, as a "++" being there for no reason at all if it won't even increment the variable does not make sense to me and I don't see the purpose of it, nor could Google show me a purpose for that path of logic. Either way, should I claim my answer does not deserve a cross (✘) or should I just accept it instead of aiming for the tick (✔) and not losing any marks.

Answer

There are two different answers here.

The correct answer, of course, is "it's undefined". Once we know that, it's pointless to investigate whether the answer might be 9, or 4, or 10, or "forty two", or "colorless green ideas", or smoke coming out of your computer screen. Far, far too many words have already been written about why it's undefined, so I won't rehearse any more of those arguments here.

But, once in a while, you find yourself dealing with an instructor who knows less than you do, meaning that if you want to get the best grade, your challenge is to figure out, not which answer is right, but which answer your instructor thinks is right.

So, bearing in mind that this second question has little or no relationship with the C Programming Language, we can ask, what might your instructor think that a = a++ * ++b could mean? There are two likely interpretations:

Interpretation 1: a++ gives 3 and assigns 4 to a, ++b gives 3 and assigns 3 to b, 3 * 3 is 9, which is assigned to a.

Interpretation 2: Like the above, but we notice that two different things get assigned to a, and we don't really know what order they'll happen in, so maybe a ends up containing 4 in the end.

Again, I'm not talking about C here. In C, we simply can't say what this expression means, other than that it's undefined. In C, wondering whether the assignment of 4 or 9 to a "happens first" is just about guaranteed to get you into trouble. Five other Stackoverflow regulars are hovering over the Comment button right now, waiting to tell me that I am just as wrong as your instructor is for even suggesting my interpretations 1 and 2 above.

But in closing, I have to say that I would consider 10 to be a much less likely result. And while I would not be surprised to get a 10, if I did get that result, it would just be because, for an undefined expression, any result is possible, and the result can be essentially random, based on goofy quirks of the compiler that no one (other than perhaps the compiler writer) will ever understand.

But to get back to your question, your assumption that one thing the compiler might do is get 9 for a, and then add 1 to it because of the a++ part, is not at all likely. The way I think about a++, and I believe a good way of thinking about how the compiler thinks about a++, is: "take a's value, add one to it, yield the old (unincremented) value out to the surrounding expression, make a note to store the incremented value back into a sometime later (but before the next sequence point)". I would not expect an actual compiler to make a note to itself to fetch a's value later and add 1 to it (yielding 10 in this case). So I'm not agreeing with your instructor that you're wrong, but I am agreeing that it's an unlikely thing for a compiler to do (although I suppose it could).