In a C programming exam question, useless and unreasonable for my standards, I found this:
int a, b=0, x=4, y=5;
a=((a=x%y?b 1:y--)&&(x-=y))||(y-=6);
I know that the correct behavior would be to shoot the programmer who wrote this, but cope with me. Is this expression UB?
I would say no, because of the sequence point (SP) between logic operators and between expressions of ?:
. So, to my understanding, the horrible hack would be evaluated correctly as:
x%y this gives 4 (exp is true)
a= b 1 this assigns 1 to a and we have a SP (exp is true)
y-- this is not evaluated
x-=y this assigns -1 to x and we have a SP (exp is true)
y-=6 this is not evaluated
a= this assigns the result of the || operator to a (1)
Finally a=1
, x=-1
, nothing else is changed. Any mistake?
CodePudding user response:
#include <stdio.h>
int main() {
int a, b=0, x=4, y=5;
a=((a=x%y?b 1:y--)&&(x-=y))||(y-=6);
printf("a=%i\nb=%i\nx=%i\ny=%i\n", a,b,x,y);
return 0;
}
OUTPUT:
a=1
b=0
x=-1
y=5
So I think you are right about everything but I do not think it counts as undefined behavior.
CodePudding user response:
I think, that expression has a completely defined behaviour.
In C, boolean expressions are evaluated from left to right.
And in Boolean algebra &&
have higher precedence than ||
.
So (a=x%y?b 1:y--)&&(x-=y))
will evaluate first and within it (a=x%y?b 1:y--)
gets evaluated first.