Dan*_*lho 2 c obfuscation sequence-points
我一直在尝试一些代码混淆的比赛(我知道这不是一个好的编程实践,但它是一个挑战我和一个朋友竞争,所以没有必要指出明显的),并在其中一个,我发现表达式有以下奇怪的行为(代码已减少到仍然重现行为的行为)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);
}
Run Code Online (Sandbox Code Playgroud)
如果我执行第一个部分,将打印0,即表达式的计算结果为0.
在第二个上,将打印0,即表达式不计算0.
在第三个,将打印1,这意味着表达式不会计算为0.
所以问题是:这些代码有什么问题?
这些代码示例导致未定义的行为,因为t--相对于t表达式的开头没有序列.
这里的排序关系是:
t--被测序-之前在三元操作者其他表达式scanf,每个参数都被排序scanf但是!=并且-没有排序关系,因此这些关系不限制t在之前进行评估,t--反之亦然,因此行为未定义.
作为一种解决方法,你可以写:
int temp = t;
printf("%d\n", temp - scanf("%d",t--?&N:&t));
Run Code Online (Sandbox Code Playgroud)
将t--被测序,之前的执行scanf机构,因此增量将之前已经平安地结束了scanf潜在的覆盖t.