2

Why does the following piece of C code print 12 12 12

int main(int argc, char const *argv[]) {
  int a = 2, *f1, *f2;
  f1 = f2 = &a;
  *f2 += *f2 += a += 2.5;
  printf("%i %i %i\n", a, *f1, *f2);
  return 0;
}
Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
shreyasva
  • 13,126
  • 25
  • 78
  • 101

3 Answers3

11
*f2 += *f2 += a += 2.5;

This line has Undefined Behavior because you change the value of *f2(i.e. a) more than once within the same expression without an intervening sequence point. UB means that your program may print "Hello World", it may crash, it may print 12 12 12 or 12 12 1029 or it may start eating your brains. Don't rely on undefined behavior.

To quote the C++ standard ( I know the question is tagged C, but I don't have a C standard by me and I know the same rule holds in C)

Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified.53) Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored. The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefined.

Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
  • Would you be so kind as to explain the reason of the downvote? – Armen Tsirunyan Jul 23 '11 at 18:12
  • I didnt down vote you, but I honestly would because of the cocky attitude you have on this post. Commenting on valid answers with "actually your wrong, its this" deserves to get a smack in the ego. Especially when you really didn't even answer the question, Peter did, you just quoted a standard and called it "magic" – SomeoneRandom Jul 25 '11 at 16:49
  • 1
    @SomeoneRandom: I did answer the question. Peter has just guessed. I hope that some day you'll understand that a language is its standard and nothing else. In the meantime, feel free to vote me down as much as you like – Armen Tsirunyan Jul 25 '11 at 21:30
  • Your answer was "i don't know, its random it could be anything" that is not true at all, it will produce the same result every time. Yes the language is defined by its standard, but he didn't ask anything about that, he wanted an explanation as to why it produced what it did. Hence, you did not answer the question. – SomeoneRandom Jul 26 '11 at 12:15
  • 1
    @SomeoneRandom: "I don't know, its random it could be anything" ***is*** the correct answer. "It will produce the same result every time" is not true. The result of an expression that violates the rule I quoted in my answer usually varies depending on the optimization level, for example. – Armen Tsirunyan Jul 26 '11 at 12:21
1

It prints out the same value for all because you are only pointing to one int variable: a.

It prints out 12 because a + 2.5 = 4 (a is an int), and then you add it to itself twice.


@Downvoters: Why so negative? I think my answer says what this compiler is doing on this example code, which should help the OP understand the behaviour. I agree that Armen Tsirunyan's answer is right (i.e. should get the tick) and that the behaviour is undefined according to the standard. But standards are implemented, and I've yet to see a compiler that compiles code and then, at run-time, suddenly throws up its hands and says Undefined behaviour!.

Community
  • 1
  • 1
Peter K.
  • 8,028
  • 4
  • 48
  • 73
1

I because *f2 and *f1 point to a (an integer).

So *f2 = &a = 2 and *f1 = &a = 2

At this point you add to a the value of 2.5 (because a is an integer, you'll obtain 4).

Than you have

a = 4
f2 = 4
f1 = 4

At this point you do f2+f1+a = 12.

Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
DonCallisto
  • 29,419
  • 9
  • 72
  • 100