【问题标题】:Unusual behavior while compiling a demo recursion code using -O3 flag使用 -O3 标志编译演示递归代码时出现异常行为
【发布时间】:2016-05-25 13:41:34
【问题描述】:

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

但是一旦我用-O3 标志编译这个确切的代码sn-p,那么输出就会变成0,这是不希望的。

代码片段

/* CODE SNIPPET FOR GENERAL RECURSION */
#include<stdio.h>
int add(int n);
int main()
{
    int n=15;
    printf("Sum of all the 15 numbers in recursion = %d  \n",add(n));
    return 0;
}

int add(int n)
{
    if(n!=0) 
      {
        printf( "N Value = %d        \n",n);
        return (n+add(n-1));  /* recursive call */
      }
}
  • 预期输出= 120

谁能告诉我 GCC 编译器是如何使用这个 -O3 标志来生成模棱两可的结果的? -O3 在做什么优化?

编译命令:

gcc     testrecursion1.c -o recursion1  # (EXPECTED OUTPUT)
gcc -O3 testrecursion1.c -o recursionO3 # (AMBIGUOUS OUTPUT)

【问题讨论】:

  • 只需添加一个别名或其他东西,以便您在启用警告的情况下编译,您应该有一个“doh!”时刻:)
  • 仅供参考,换行符前的尾随空格毫无意义。
  • 您使用的是哪个版本的 GCC? 4.1.2、5.3.0、6.1.0,还有别的吗?这可能很重要。你声称的输出是你应该得到的总输出的一小部分——给出了什么?
  • -Wall 添加到编译命令行。解决问题!以后不要在没有-Wall 的情况下编译。 (我在运行代码之前使用了更广泛的警告选项:-std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror 或更多。

标签: gcc compilation compiler-errors


【解决方案1】:

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

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

为避免这种情况发生,不要在程序中硬编码n=15,而是将它作为你程序的参数(这样编译器就不会知道n 的哪些值可以传入,并且所以不能专门化这些值的代码)。

例如:

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

然后运行:./recursionO3 15

【讨论】:

  • 非常感谢.. 感谢您花时间解释场景
猜你喜欢
  • 2018-04-08
  • 2012-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多