是gcc的选项-O2打破这个小程序还是我具有不确定的行为 [英] Is GCC's option -O2 breaking this small program or do I have undefined behavior
问题描述
我发现了一个非常大的应用程序这个问题,从它做了SSCCE。我不知道code是否未定义的行为或 -O2
打破它。
在与编译它的gcc -o变交流A.EXE -O2 -Wall -Wextra -Werror
它打印的 5 。
但它打印的 25 不编译时 -O2
(如 -O1
)或取消注释2注释行之一(prevent内联)。
的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
// __attribute __((noinline始终))
INT F(INT *待办事项,INT输入){
为int * CUR =待办事项-1; //修复++在循环的开始
INT结果=输入;
而(1){
CUR ++;
INT CH = * CUR;
//的printf((%I)\\ n,CH);
开关(CH){
案件0:;
转到结束;
情况1:;
结果=结果*结果;
打破;
}
}
结束:
返回结果;
}
诠释主(){
INT待办事项[] = {1,0}; // 1:方形,0:结束
INT输入= 5;
INT结果= F(待办事项,输入);
的printf(=%I \\ N,结果);
的printf(结束\\ n);
返回0;
}
是gcc的选项 -O2
打破这个小程序或者我有什么地方未定义的行为?
为int * CUR =待办事项-1;
调用未定义的行为。 待办事项 - 1
是一个无效的指针地址
重点煤矿:
(C99,6.5.6p8)如果指针操作数和结果指向相同的数组对象的元素,或者一个过去的数组对象的最后一个元素都,该评估也不得产生溢出; 否则,行为是不确定的。
块引用>I found this problem in a very large application, have made an SSCCE from it. I don't know whether the code has undefined behavior or
-O2
breaks it.When compiling it with
gcc a.c -o a.exe -O2 -Wall -Wextra -Werror
it prints 5.But it prints 25 when compiling without
-O2
(eg-O1
) or uncommenting one of the 2 commented lines (prevent inlining).#include <stdio.h> #include <stdlib.h> // __attribute__((noinline)) int f(int* todos, int input) { int* cur = todos-1; // fixes the ++ at the beginning of the loop int result = input; while(1) { cur++; int ch = *cur; // printf("(%i)\n", ch); switch(ch) { case 0:; goto end; case 1:; result = result*result; break; } } end: return result; } int main() { int todos[] = { 1, 0}; // 1:square, 0:end int input = 5; int result = f(todos, input); printf("=%i\n", result); printf("end\n"); return 0; }
Is GCC's option
-O2
breaking this small program or do I have undefined behavior somewhere?解决方案int* cur = todos-1;
invokes undefined behavior.
todos - 1
is an invalid pointer address.Emphasis mine:
(C99, 6.5.6p8) "If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined."
这篇关于是gcc的选项-O2打破这个小程序还是我具有不确定的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!