2
int main() {
  int a = 10;
  int b = a * a++;
  printf("%i %i", a, b);
  return 0;
}

Is the output of the above code undefined behavior?

shreyasva
  • 13,126
  • 25
  • 78
  • 101
  • What part of it (are you suspecting to be implementation-dependant)? – flight Mar 04 '11 at 10:20
  • It's undefined behavior, so implementation dependent. – Erik Mar 04 '11 at 10:20
  • @Erik: *undefined behavior* and *implementation dependent* are two different terms that are explicitly defined in the standard. I read that somewhere on SO, but I cannot find it right now. – Björn Pollex Mar 04 '11 at 10:21
  • @Erik, there are different requirements for both of them. When something is implementation defined, the behavior has to be consistent and documented, when something is undefined behavior you might get different results. Think on accessing `v[ v.size() ]` in a vector, which is UB. In many systems, if `v.size()==v.capacity()` that will trigger a segmentation fault and the application will die, but if `v.size() < v.capacity()` you will just be accesing random bits of memory that belong to the same container, it will be wrong but unluckily the application won't die. – David Rodríguez - dribeas Mar 04 '11 at 10:27
  • To me, `a++ + ++a` is a much more interesting case. – Andrew Marshall Mar 04 '11 at 10:27
  • @Space, @David: I should've phrased it "dependent on the compiler" to avoid the "implementation dependent" phrase. Same compiler tends to produce same result for these scenarios, although it's not documented/defined in any way. – Erik Mar 04 '11 at 10:30
  • @Erik: The compiler is not required to produce same results for undefined behavior. – sharptooth Mar 04 '11 at 10:34
  • @sharptooth: No, that's why my comment said "tends to" not "will" :) – Erik Mar 04 '11 at 10:34
  • @Erik: Yes, I noticed, but you should never say anything like that until you thoroughly verified the compiler source code and even then your knowledge will become invalid once an update is shipped. – sharptooth Mar 04 '11 at 10:37
  • The difference would be that implementation-defined means that the compiler will and must implement it, in some manner of its own. While undefined behaviour means that it is beyond the standard and nobody has to implement it. Meaning that anything may happen if the undefined behaviour is invoked, including devastating computer crashes. – Lundin Mar 04 '11 at 10:43
  • This is "yet another sequence points" question. – CashCow Mar 04 '11 at 11:15

1 Answers1

6

No in

int b = a * a++;

the behavior is undefined, so the result can be anything - that's not what "implementation dependent" means.

You might wonder why it's UB here since a is modified only once. The reason is there's also a requirement in 5/4 paragraph of the Standard that the prior value shall be accessed only to determine the value to be stored. a shall only be read to determine the new value of a, but here a is read twice - once to compute the first multiplier and once again to compute the result of a++ that has a side-effect of writing a new value into a. So even though a is modified once here it is undefined behavior.

Community
  • 1
  • 1
sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • How is it undefined? a is guaranteed to be incremented after the whole expression is evaluated. That is a quite different matter than something like ++i = i, which would be implementation-defined behaviour (order of evaluation). Is C++ different than C in this regard? – Lundin Mar 04 '11 at 10:36
  • @Lundin: The question I link to has a very good top answer which explains this in all possible details - I just can't add anything to that. – sharptooth Mar 04 '11 at 10:42
  • Yes I am aware of all that. I just don't see how it applies to this particular case. You have one sequence point at the end of the expression, and two side effects: b is modified, a is modified. Each variable is only modified once before the end of the sequence point. What undefined behaviour is invoked and where? – Lundin Mar 04 '11 at 13:06
  • 1
    @Lundin: Please note the *Furthermore, the prior value shall be accessed only to determine the value to be stored.* part of the Standard 5/4 wording - it applies right here. – sharptooth Mar 04 '11 at 13:51
  • I see, this is new to me then. I've always regarded it as "unspecified behaviour". That particular wording in the standard isn't all that clear, and I can see that the very same wording exists in the C standard. To make things worse, both the C and C++ standards illustrate with examples that also depend on the order of evaluation, i.e. unspecified behaviour and undefined behaviour on the same line. Does anyone know if this was undefined behaviour back in C89 as well? – Lundin Mar 04 '11 at 14:38