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==9t-(t^14)==2 所以 t 变成 1.

在第二次迭代中 t==1t-(t^14)!=2 所以 t 变成 41.

在第三次迭代中 t==41t-(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 #2Pass #3 之间翻转。 (t=1 和 t=41)。

无限循环是正确的结果。

(在你真的相信你发现了一个编译器错误之前,你需要聪明一百万倍。)