gcc优化给出无限循环或段错误

时间:2015-03-11 16:49:12

标签: c gcc optimization segmentation-fault undefined-behavior

我刚刚发现了一个非常有趣的代码。 GCC优化很奇怪地改变了它的行为。

  • -O0正常工作
  • -O1 segfault
  • -O2无限循环(从7到1996年)
  • -O3的作品
  • -Og segfault
  • -Ofast works

以下是代码:

int main(int argc, char *argv[])
{
  int i, c;

  c = 0;
  for (i = 10; i < 10000; ++i)
    {
      if (is_lychrel(i))
        ++c;

      printf("%d\n", i);
    }

  printf("%d\n", c);

  return EXIT_SUCCESS;
}

函数is_lychrel(int)使用参数。

据我所知,这可能是由于某处未定义的行为,但我无法发现它。我试图禁用一些优化标志,但到目前为止我没有运气。

如果您需要更多代码,请随时提出。

修改 正如评论中所建议的,我试图评论一些函数,最后调试了旧的学校方式(因为gdb不起作用)。我找到了罪魁祸首(至少是段错误):

void add_reverse(int d[], int *len)
{
  int i;
  int plus[28] = {0};

  for (i = 0; i < *len; ++i)
    {
      //printf("d %d\n", i);

      plus[i] = d[*len - i - 1];
    }

  add(d, plus, len);
}

假设此函数向其反向添加一个数字(作为数字数组)并返回新长度。例如:({1, 2}, 2)应该({3, 3}, 2)。它不会与printf发生段错误,但不会产生良好的结果。我正在尝试逐步分析d []。在[segfault]之前d []是0034647260072070369072646341(似乎有效)。

编辑2: 在计算plus后,添加一个简单的显示循环(显示循环是不够的),纠正 -O1 的输出。

  for (i = 0; i < *len; ++i)
    printf("%d", plus[i]);

以下是add()代码,如果可能有所帮助:

void add(int d[], int plus[], int *maxlen)
{
  int i, of;

  of = 0;
  for (i = 0; i <= *maxlen; ++i)
    {
      d[i] += plus[i];

      if (of)
        {
          d[i] += of;
          of    = 0;
        }

      if (d[i] >= 10)
        {
          of    = 1;
          d[i] %= 10;
        }
    }

  if (d[i - 1])
    ++*maxlen;
}

1 个答案:

答案 0 :(得分:0)

简单。我的阵列太小了。由于某种原因,我确信尺寸,但我肯定是错的。我应该先检查一下。

现在每个优化级别都能正常运行。