#include<stdio.h>
int main()
{
int a=4;
int b=4;
int c= a++ < ++b? 1 : 0;
printf ("%d",c);
}
It is known that there is a sequence point at ?, which means that both the prefix and postfix operations have to be completed by that point. Also it is known(?) that b is incremented before the comparison. However, is a incremented before or after the comparison?
If it is incremented before the < test, then the Boolean evaluates to false and c is set to 0, else to true with c being set to 1. In my compiler, it evaluates to true, which means a++ is performed after the comparison operation with c being set to 1.
Is this behavior part of the specification though?
I modified it to
#include<stdio.h>
int main()
{
int a=4;
int b=4;
int d=2;
int c= a++ + d < ++b + d? 1 : 0;
printf ("%d",c);
}
and it still evaluates to 1. The postfix has to complete before the ?, but does that really ensure that it happens after the comparison < ?
This is a subtle point, but it's important to understand what's really going on here.
Both the subexpressions
a++and++bdo two things. They compute a new value to be used in the surrounding expression, and they update the stored value of the variable they're operating on.So
a++does this:a(4) out to the surrounding expressiona.And
++bdoes this:b(4+1 or 5) out to the surrounding expressionb.Notice that in both cases it's thing 1 that the
<operator cares about. And, in both cases, thing 1 is an absolute definition, it doesn't depend on timing.Or, in other words, asking "Is
a/bincremented before or after the comparison?" is not really the right question. The valuesaandb+1participate in the comparison, and that's it.Where the timing comes in is things 2. We don't know, precisely, when the new value gets stored back into
a. Nor do we know precisely when the new value gets stored back intob. All we know is that those stores will happen sometime before the next sequence point (which, as you correctly note, in this case is the?part of the ternary operator).But nothing depends on those timings, so there's no undefined behavior here.
Undefined behavior comes in when either
aorb) also has its value independently used elsewhere in the expression, meaning that we don't know whether that use uses the old or the new valueBut, again, neither of those problems occurs here, so the expression is well-defined.