简体   繁体   中英

How can this C code evaluate to 0 and not 0 at the same time?

I have been trying some contests on code obfuscation (I know it is not a good programming practice, but it was a challenge me and a friend are competing, so there's no need to point out the obvious), and, in one of those, I found the following weird behaviour (code has been reduced to one that still reproduces the behaviour) for the expression t-scanf("%d",t--?&N:&t) :

int main(int t, int N){
    printf("%d\n",t-scanf("%d",t--?&N:&t));
}

int main(int t, int N){
    printf("%d\n",t-scanf("%d",t--?&N:&t)==0);
}

int main(int t, int N){
    printf("%d\n",t-scanf("%d",t--?&N:&t)!=0);
}

If I execute the first piece, 0 will be printed, that is, the expression evaluates to 0.

On the second one, 0 will be printed, that is, the expression does not evaluate a 0.

On the third, 1 will be printed, meaning that the expression does not evaluate to 0.

So the question is: What's wrong with these pieces of code?

These code examples cause undefined behaviour because t-- is unsequenced with respect to the t at the start of the expression.

The sequencing relations here are:

  • t-- is sequenced-before the other expressions in the ternary operator
  • The arguments to scanf are each sequenced-before using the return value of scanf

However != and - have no sequencing relation, so those relations do not constrain t to be evaluated before t-- or vice versa, therefore the behaviour is undefined.


As a workaround you could write:

int temp = t;
printf("%d\n", temp - scanf("%d",t--?&N:&t));

The t-- is sequenced-before the execution of the scanf body, so the increment will have safely finished before scanf potentially overwrites t .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM