当我在for循环中遇到一个if循环而编译器无法优化时,我得到了难以置信的奇怪行为。似乎只有循环的遍历才能到达a = 0
,但没有提前终止。一个例子是这样的:
#include <iostream>
int main() {
for (int a = -5; a < 5; a++) {
std::cout << a << std::endl;
//if (rand() % a) {} // uncommenting this line gives the weird results
}
}
以上述方式运行时,我得到了预期的输出,
-5
-4
-3
-2
-1
0
1
2
3
4
但是,当我取消注释该行(if内没有内容)时,我得到以下输出:
-5
-4
-3
-2
-1
0
for循环似乎一直在运行,直到到达a = 0
。仅当存在if(带或不带主体)且优化设置为-O0
或-O1
时,我才得到第二个奇怪的结果。我在Windows 10上运行的GCC版本为6.3.0的MinGW。
答案 0 :(得分:6)
答案在%
语句的mod运算符(if
)中找到。
Mod 0是未定义的行为(就像您被零除)一样。因此,一切都会发生,任何事情都会发生-对程序的行为没有任何限制。就您而言,循环不会继续。
二进制运算符%产生第一个操作数除以第二个操作数的整数除法的余数(在通常的算术转换之后;请注意,操作数类型必须是整数类型)。如果商a / b在结果类型中可表示,则(a / b)* b + a%b == a。 如果第二个操作数为零,则行为未定义。如果结果类型中无法表示商a / b,则a / b和a%b的行为均未定义(这意味着INT_MIN %-1在2的补码系统中未定义)