C 复合条件未按预期工作(值神秘地重新分配给其他值)- 可能是 gcc 错误
C compound conditional not working as expected (value mysteriously reassigned to other value) - possible gcc bug
我有一个程序由于 gcc 中可能存在的错误而陷入循环。我已经在多个版本的编译器上对此进行了测试,它似乎仍然存在。该错误的模型版本是
#include <stdio.h>
#include <stdlib.h>
#define db printf("t=%d\n", t)
size_t t = 9;
int main(int argc, char** args) {
l: //label so we can repeat
t-(t^14) //works as expected if this line is changed to t-7, but t xor 14 = 7... this line is also executed ONCE
==2?db,t=1: //end of first conditional, next line starts the second
t==1?db,t=41: //buggy ONLY if t=40 or 41 on this and next line
t==41?db,t=0: //bug in this line (after this line executes, t = 1 no matter what)
t==0?exit(0): //terminates if not buggy
0;
goto l; //repeat
}
请不要问我为什么使用这个,因为它是为了混淆代码竞赛,而我正在使用这种特殊方法。
我也想知道这是否是意外行为,但我怀疑是。
谢谢
打印的 t
的值在 1 和 41 之间交替,所以当你的程序被解开时,为什么 exit(0)
永远不会被执行就变得很明显了。
在第一次迭代中 t==9
和 t-(t^14)==2
所以 t
变成 1.
在第二次迭代中 t==1
和 t-(t^14)!=2
所以 t
变成 41.
在第三次迭代中 t==41
和 t-(t^14)==2
所以 t
变成 1.
现在重复第二次迭代。
#include <stdio.h>
#include <stdlib.h>
size_t t = 9;
int main(int argc, char** args) {
l: //label so we can repeat
if (t-(t^14) == 2) {
printf("t=%d\n", t);
t=1;
}
else if (t==1) {
printf("t=%d\n", t);
t=41;
}
else if (t==41) {
printf("t=%d\n", t);
t=0;
}
else if (t==0)
exit(0);
else
0;
goto l;
}
我用缩进和注释重写了你的表达式,以便可以追踪。
t-(t^14)==2?
/*True */ db,t=1
/*else */ :
/*False*/ t==1?
/*True */ db,t=41
/*else */ :
/*False*/ t==41?
/*True */ db,t=0
/*else */ :
/*False*/ t==0?
/*True */ exit(0)
/*else */ :
/*False*/ 0;
现在追溯:
通过 #1
t = 9
t^14 = 7
t-7 == 9 - 7 == 2, therefore Condition 1 is True.
printf 9, t = 1, goto top.
通过 #2
t=1
t^14 = 15
t-15 = -14 != 2, therefore condition 1 is False.
Condition 2: t==1? TRUE,
printf 1, t = 41, goto top.
通过 #3
t = 41
t^14 = 39
41-39 = 2, therefore Condition 1 is true.
Printf 41, t = 1, goto top.
因为 t 现在回到值 1,我们回到与第 2 关相同的场景。
循环不断地在 Pass #2 和 Pass #3 之间翻转。 (t=1 和 t=41)。
无限循环是正确的结果。
(在你真的相信你发现了一个编译器错误之前,你需要聪明一百万倍。)
我有一个程序由于 gcc 中可能存在的错误而陷入循环。我已经在多个版本的编译器上对此进行了测试,它似乎仍然存在。该错误的模型版本是
#include <stdio.h>
#include <stdlib.h>
#define db printf("t=%d\n", t)
size_t t = 9;
int main(int argc, char** args) {
l: //label so we can repeat
t-(t^14) //works as expected if this line is changed to t-7, but t xor 14 = 7... this line is also executed ONCE
==2?db,t=1: //end of first conditional, next line starts the second
t==1?db,t=41: //buggy ONLY if t=40 or 41 on this and next line
t==41?db,t=0: //bug in this line (after this line executes, t = 1 no matter what)
t==0?exit(0): //terminates if not buggy
0;
goto l; //repeat
}
请不要问我为什么使用这个,因为它是为了混淆代码竞赛,而我正在使用这种特殊方法。
我也想知道这是否是意外行为,但我怀疑是。
谢谢
打印的 t
的值在 1 和 41 之间交替,所以当你的程序被解开时,为什么 exit(0)
永远不会被执行就变得很明显了。
在第一次迭代中 t==9
和 t-(t^14)==2
所以 t
变成 1.
在第二次迭代中 t==1
和 t-(t^14)!=2
所以 t
变成 41.
在第三次迭代中 t==41
和 t-(t^14)==2
所以 t
变成 1.
现在重复第二次迭代。
#include <stdio.h>
#include <stdlib.h>
size_t t = 9;
int main(int argc, char** args) {
l: //label so we can repeat
if (t-(t^14) == 2) {
printf("t=%d\n", t);
t=1;
}
else if (t==1) {
printf("t=%d\n", t);
t=41;
}
else if (t==41) {
printf("t=%d\n", t);
t=0;
}
else if (t==0)
exit(0);
else
0;
goto l;
}
我用缩进和注释重写了你的表达式,以便可以追踪。
t-(t^14)==2?
/*True */ db,t=1
/*else */ :
/*False*/ t==1?
/*True */ db,t=41
/*else */ :
/*False*/ t==41?
/*True */ db,t=0
/*else */ :
/*False*/ t==0?
/*True */ exit(0)
/*else */ :
/*False*/ 0;
现在追溯:
通过 #1
t = 9
t^14 = 7
t-7 == 9 - 7 == 2, therefore Condition 1 is True.
printf 9, t = 1, goto top.
通过 #2
t=1
t^14 = 15
t-15 = -14 != 2, therefore condition 1 is False.
Condition 2: t==1? TRUE,
printf 1, t = 41, goto top.
通过 #3
t = 41
t^14 = 39
41-39 = 2, therefore Condition 1 is true.
Printf 41, t = 1, goto top.
因为 t 现在回到值 1,我们回到与第 2 关相同的场景。 循环不断地在 Pass #2 和 Pass #3 之间翻转。 (t=1 和 t=41)。
无限循环是正确的结果。
(在你真的相信你发现了一个编译器错误之前,你需要聪明一百万倍。)