可能重复:
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)
我的朋友和我正在弄乱我们想到的最糟糕的循环(所以不要告诉我这是可怕的代码,因为它应该是!)。
我的朋友想出了这个循环:
for (int i = 0; i++ & ++i % (++i % 2) ? --i : i++; i++);
它看起来没问题,但由于浮点异常,它甚至第一次都无法进入。 所以我的第一个想法是模数除以0.但它似乎没有,因为如果你这样做,它运行良好:
for (int i = 0; i < 100; i++) {
i++ & ++i % (++i % 2);
}
但这不会:
for (int i = 0; i < 100; i++) {
i++ & ++i % (++i % 2) ? --i : i++;
}
但它变得陌生。第一种情况运行良好,第二种情况不会:
for (int i = 0; i < 100; i++) {
i++ & ++i % (++i % 2) ? 0 : 1;
}
for (int i = 0; i < 100; i++) {
i++ & ++i % (++i % 2) ? 1 : 0; // 1 and 0 switched
}
所以到现在为止我真的很困惑,但它又变得更奇怪了。如果你将? 0 : 1
(运行正常)的情况放入if语句,它会再次抛出浮点异常:
for (int i = 0; i < 100; i++) {
if (i++ & ++i % (++i % 2) ? 0 : 1);
}
我完全迷失了。有人知道这里发生了什么吗?
答案 0 :(得分:3)
i++ & ++i
出错了。 &
运算符不对其操作数进行排序,因此在两侧都加上一个增量会导致未定义的行为。
顺便说一下,它可能是零除外,但不一定来自FPU。
答案 1 :(得分:1)
通常,在C和C ++中的单个表达式中混合使用此类多个增量操作是一个坏主意,因为它通常会导致未定义的行为。对于未定义的行为,让事物神秘地改变行为并不令人惊讶。
另一方面,Java为所有算术和逻辑运算提供了严格的规范(非fpstrict表达式中的浮点指数精度除外)。您可以将所有这些放入Java中(忽略int不再是有效的布尔表达式这一事实)并让它们给出一致的答案,尽管它可能不是您所期望的。