12

I know this looks familiar but it is brought to me as a problem in a test by Microsoft to recruit interns. It seems to me that y=++y is not standard compliant, but I think maybe it would be better to be sure (not sure that I'm better than those who write up these tests at MS). So I'm asking your advice. Do you think expressions like this is standard-compliant and does not result in undefined behaviour?

#include <stdio.h>
int main(){
    int a = 10;
    int b = 10;
    a = ++a;    //What ???
    b = b++;    //What ???
    printf("%d %d\n",a,b);
    return 0;
}

gcc complains about it when used to compile with -Wsequence-point. (It is not explicitly stated whether it is a C or C++ specific problem.)

But only four answers provided:

a) 10 10
b) 11 10
c) 10 11
d) 11 11

Although one is not restricted to select only one answer ( so maybe I should choose all four? )

Well, in my opinion, between self-incrementing and assignment there is no sequence point. So this violates the specification. Doesn't it?

TecBrat
  • 3,643
  • 3
  • 28
  • 45
phoeagon
  • 2,080
  • 17
  • 20

4 Answers4

9

They're both well-defined behaviour as per C++11. C++11 doesn't even have sequence points, so a sequence-point related warning is obviously outdated. The assignment operator imposes sequencing on its arguments.

Edit:

Whilst everyone can agree that i = ++i is now well-defined behaviour, it is rather non-trivial to decide the definedness of i = i++. Intuitively, I should describe it as well-defined, but the Standard clearly states that

i = i++ + 1;

is UB, and I'm not seeing the + 1 making any difference here.

The short is, if you wanted to answer this question, you would need to be an expert on the decidedly non-trivial C++11 sequencing rules, which it appears that I am not, but it appears that the answer is "None of the above because UB".

Ry-
  • 218,210
  • 55
  • 464
  • 476
Puppy
  • 144,682
  • 38
  • 256
  • 465
  • @DeadMG Could you answer an additional question, since you answered the original one: shouldn't the result be `11 12` in C++11? – lapk Apr 08 '13 at 10:40
  • No. Why would it be? And also, ask another question. – Puppy Apr 08 '13 at 10:41
  • @DeadMG Because `b = 11;` and `b = b++;` makes `b` still equal to `11` , and we have post-increment that makes `b` equal to `12` in `printf`... Sorry, I didn't think it was worth a separate question and I couldn't understand why there wasn't such choice in the original list... Maybe, I'm misunderstanding something, just thought to clarify. – lapk Apr 08 '13 at 10:45
  • Actually, I've changed my mind now! `b = b++` *is* undefined behaviour. Posting an answer to describe why. – Joseph Mansfield Apr 08 '13 at 10:49
  • 1
    so, what is the correct answer? I thought this is ub – BЈовић Apr 08 '13 at 10:51
  • @sftrabbit: It's certainly non-trivial to decide if it is UB or not. – Puppy Apr 08 '13 at 11:01
  • 3
    @DeadMG Okay, I present [the argument in paper form](http://i.imgur.com/Ep3mcBu.jpg)! An arrow means "sequenced before". "V.C." stands for value computation. The reason this is undefined behaviour is because the two starred nodes in the graph are unsequenced. The main cause of this is from the post-fix increment section of the standard: "The value computation of the ++ expression is sequenced before the modification of the operand object." – Joseph Mansfield Apr 08 '13 at 11:09
4

As per C++03 standard,
Both of the below statements result in undefined behavior:

a = ++a;
b = b++;

As you correctly stated, g++ points out below warning:

warning: operation on ‘a’ may be undefined [-Wsequence-point]

Note that in case of UB, the answer can be anything apart from (a), (b), (c), (d).
Ideally there should be an option for "undefined behavior" in the test question. But often, the person who prepares the question would simply compile in XYZ compiler and submit it.

Here is a related SO post explaining Undefined Behavior and Sequence Points.

Community
  • 1
  • 1
iammilind
  • 68,093
  • 33
  • 169
  • 336
0

a = ++a; b= b++; These operations are considered as undefined. Each compiler can do as its wish. output varies on compiler the examiner framed the question.

shivakumar
  • 3,297
  • 19
  • 28
-4

I think it's D) since ++a means increment a and then execute the operation, so it will be like doing a=11. b++ means do the operation and then increment, so you'll be assigning b=10 but then b is incremented giving it the value b=11.

Well for the purists: It doesn't "mean anything and then anything", but that's it's behavior. I tested it (using visual c++ and g++) and my answer is correct a=11 and b=11.

Mppl
  • 941
  • 10
  • 18
  • It doesn't mean "something *and then* something". – R. Martinho Fernandes Apr 08 '13 at 10:34
  • Well, I don't need *empirical result*. Almost all popular compilers used nowadays exhibit this behaviour. But I want to know if it is **required** to do so or just a fallback method that could be either adopted or not. – phoeagon Apr 08 '13 at 10:38
  • 3
    It's impossible to "test" undefined behaviour, because it's undefined and each and every implementation can do whatever the hell it wants to. (That's regardless of original question btw) – Cat Plus Plus Apr 08 '13 at 10:38