【问题标题】:gcc -O3 flag causes warnings that -O2 doesn'tgcc -O3 标志会导致警告 -O2 不会
【发布时间】:2013-04-30 20:02:05
【问题描述】:

我正在构建一个相当复杂的应用程序,它使用-O0 构建时没有任何错误/警告。然而,当我尝试-O3 时,我得到了一些令人费解的问题。例如:

1: static pinfo_t* pinfo[2] = { &gv1, &gv2 }; // GLOBAL
2: 
3: int i;
4: int x = sizeof(pinfo);
5: 
6: for (i = 0; i < x; i ++)
7:    if (pinfo[i]->id == NO_ID)
8:        printf("%s\n", pinfo[i]->name);

请注意,编译器 (gcc v4.3.2) 使用 -O0 成功构建了它(也使用 O1 和 O2)。但是使用-O3,编译器正确地指出第7行是一个潜在的问题,导致出现错误的行:

error: array subscript is above array bounds

还不错,但是当我注释掉第7行时,第8行没有问题,应该也被标记了!

感谢任何帮助!

【问题讨论】:

  • 过度匿名。如果我假设 while = for,我会看到不应引发错误的代码。
  • 您的 while 循环不正确。了解正在发生的事情的一个好方法是查看为您的 while 循环生成的程序集。
  • @Joshua 我看到一个循环访问pinfo2 * sizeof(pinfo_t *) 元素。 sizeof(pinfo_t *) 在所有主要(和许多次要)平台上都大于 1,因此它会超出范围。
  • 正如所写,您的问题有很多问题。主题说-O2,但在正文中你说-O0。然后你问关于注释掉第 6 行的问题。你遇到的真实情况是什么,你想知道什么?
  • @Étienne: 是的,它似乎也是假代码......

标签: c optimization gcc compiler-optimization


【解决方案1】:

Wrt 警告和优化级别,在 GCC 中,在优化传递期间分析代码时会生成一些警告,因此当这些传递未启用时,也不会发出这些警告。这是一个长期存在的问题,但到目前为止,它还没有在任何人的 TODO 列表上传播得足够高。

【讨论】:

  • 哎呀,所以如果我想要快速编译 (-O0),那么我不会收到所有警告......好吧,很高兴知道。我当然希望-O2 打开所有警告,因为我再也不用-O3 编译了。
【解决方案2】:

编译器将 -O3 处的循环完全展开为类似以下内容的甜甜圈:

...

if (pinfo[0]->id == NO_ID)
    printf("%s\n", pinfo[0]->name);
if (pinfo[1]->id == NO_ID)
    printf("%s\n", pinfo[1]->name);
if (pinfo[2]->id == NO_ID)
    printf("%s\n", pinfo[2]->name);

...

然后它会观察到生成的索引超出范围并警告您。

【讨论】:

  • 这是有道理的,除了注释掉'if'时没有错误。
  • 这没什么好说的。谁知道编译器在做什么优化以及它如何处理if 语句中的pinfo[i]
  • 啊,也许吧。似乎我将不得不花费相当长的时间来修复代码:/
猜你喜欢
  • 1970-01-01
  • 2015-05-06
  • 1970-01-01
  • 1970-01-01
  • 2015-12-25
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 2023-03-17
相关资源
最近更新 更多