ats*_*ich 1 c++ optimization evaluation gcc while-loop
当使用g++ -O3 ..和不使用时,以下代码具有不同的行为-O3。
我知道这updateError不会返回任何东西,这可能导致不确定的行为。我不明白的是,error如果使用-O3 if(error > eps)进行编译,则在循环内将其设置为零,并且被评估为false,而在while()语句中仍被评估为true 。。
我还尝试将其更改为do {} while()循环,在这种情况下,它也可以与-O3一起使用...
#include <stdio.h>
using namespace std;
double updateError(){
printf("updating Error\n");
}
int main(int argc, char *argv[]){
double eps = 1.e-10;
double error = 2*eps;
int iter = 0;
while(error > eps){
error = updateError();
iter++;
printf("Error on iteration %i: %.20e\n", iter, error);
if(error > eps) printf("error bigger\n\n");
else printf("error smaller\n\n");
if(iter == 5){
printf("not converged in 5 iterations!!\n");
break;
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
带有-O3的控制台输出:
updating Error
Error on iteration 1: 0.00000000000000000000e+00
error smaller
updating Error
Error on iteration 2: 0.00000000000000000000e+00
error smaller
updating Error
Error on iteration 3: 0.00000000000000000000e+00
error smaller
updating Error
Error on iteration 4: 0.00000000000000000000e+00
error smaller
updating Error
Error on iteration 5: 0.00000000000000000000e+00
error smaller
not converged in 5 iterations!!
Run Code Online (Sandbox Code Playgroud)
不带-O3的控制台输出:
updating Error
Error on iteration 1: 6.92743341769227318242e-310
error smaller
Run Code Online (Sandbox Code Playgroud)
for*_*818 10
我知道updateError不返回任何东西,这可能导致未定义的行为。
没有“可以”。您的代码具有未定义的行为。期。
在调试时,编译器会做一些额外的工作来增强调试器的使用。这可以像是实际上不必初始化变量时那样。在优化的构建中不会完成这种开销。无论如何,如果您想了解为什么获得结果,那么您应该看一下组装。请注意,UB是UB,因此您无法保证在第二天使用相同的编译器可获得相同的结果。
我不明白的是,如果使用-O3进行编译,则在循环内将错误设置为零,并且if(error> eps)的评估结果为false,而while()语句中的评估结果仍然为true。。
请注意,您编写的代码不会逐行转换为CPU的指令。编译器非常聪明,并且会在视情况规则下应用各种转换。只要可观察到的行为相同,编译器就可以将您的代码转换为与天真的逐行转换完全不同的东西。但是,如果您的代码具有UB,则它不是有效的c ++代码,并且对于一个相同的变量获取不同的输出并不令人感到意外。