Gcc 使用-O3标志编译演示递归代码时出现异常行为

Gcc 使用-O3标志编译演示递归代码时出现异常行为,gcc,compilation,compiler-errors,Gcc,Compilation,Compiler Errors,当我通常在x86机器上使用GCC编译器编译下面提到的代码段时,我会得到预期的输出120 但是,当我使用-O3标志编译这个精确的代码片段时,输出结果是0,这是不需要的 代码片段 默认情况下,GCC使用-O0(减去ooh零),这意味着“根本不优化” 然而,一旦您启用优化,编译器将进行大量优化,在这种特殊情况下,将您的add函数专门用于提供的输入。最后一次对add的调用将针对n=0,因此这就是最终的版本 为了避免这种情况发生,不要在程序中硬编码n=15,而是将其作为程序的参数(这样编译器就不知道可以传

当我通常在x86机器上使用GCC编译器编译下面提到的代码段时,我会得到预期的输出120

但是,当我使用
-O3
标志编译这个精确的代码片段时,输出结果是0,这是不需要的

代码片段 默认情况下,GCC使用-O0(减去ooh零),这意味着“根本不优化”

然而,一旦您启用优化,编译器将进行大量优化,在这种特殊情况下,将您的
add
函数专门用于提供的输入。最后一次对
add
的调用将针对
n=0
,因此这就是最终的版本

为了避免这种情况发生,不要在程序中硬编码
n=15
,而是将其作为程序的参数(这样编译器就不知道可以传入
n
的哪些值,因此无法专门为这些值编写代码)

例如:

int main(int argc, char* *argv){
    int n=atoi(argv[1]);
    ...
然后运行:
/recursionO3 15

默认情况下,GCC使用-O0(减去ooh零),这意味着“根本不优化”

然而,一旦您启用优化,编译器将进行大量优化,在这种特殊情况下,将您的
add
函数专门用于提供的输入。最后一次对
add
的调用将针对
n=0
,因此这就是最终的版本

为了避免这种情况发生,不要在程序中硬编码
n=15
,而是将其作为程序的参数(这样编译器就不知道可以传入
n
的哪些值,因此无法专门为这些值编写代码)

例如:

int main(int argc, char* *argv){
    int n=atoi(argv[1]);
    ...

然后运行:
/recursionO3 15

只需添加一个别名或其他东西,这样您就可以在启用警告的情况下编译,并且您应该有一个“doh!”时刻:)作为参考,换行符前的尾随空格是毫无意义的。您使用的是哪个版本的GCC?4.1.2,5.3.0,6.1.0,还有别的吗?这可能很重要。您声明的输出是您应该获得的总输出的一小部分-给出了什么?将
-Wall
添加到编译命令行。解决问题!以后在没有
-Wall
的情况下不要编译。(在运行代码之前,我使用了更广泛的警告选项:
-std=c11-Wall-Wextra-Wmissing prototype-Wstrict prototype-Wold-style definition-Werror
或更多。只需添加一个别名或其他内容,以便在启用警告的情况下编译,您应该有一个“doh!”时刻:)仅供参考,换行符前的尾随空格是毫无意义的。您使用的是哪个版本的GCC?4.1.2,5.3.0,6.1.0,还有别的吗?这可能很重要。您声明的输出是您应该获得的总输出的一小部分-给出了什么?将
-Wall
添加到编译命令行。解决问题!以后在没有
-Wall
的情况下不要编译。(我在运行代码之前使用了更广泛的警告选项:
-std=c11-Wall-Wextra-Wmissing prototype-Wstrict prototype-Wold style definition-Werror
或更多。非常感谢您花时间解释场景非常感谢您花时间解释场景
int main(int argc, char* *argv){
    int n=atoi(argv[1]);
    ...