在旧g ++中重新定义for循环变量

时间:2013-07-07 17:56:55

标签: c++ for-loop g++ declaration compiler-options

在某些C ++代码(为GCC编写)上运行git bisect时,我遇到了由

行引起的编译器错误
#include <stdio.h>

int main() {
  for (int i = 0; i < 10; ++i) {
    long i = 0;
    printf("%ld\n", i);
  }
  return 0;
}

这段代码,我相信,完全标准的C99(gcc -std=c99编译得很好),但g++i的重新声明而失败。答案https://stackoverflow.com/a/12351531/560450在这个问题上引用了C ++ 11标准:

  

6.4 / 2条件规则既适用于选择语句,也适用于for和while语句

     

6.4 / 3如果在由条件控制的子语句的最外层块中重新声明名称,则声明   重申这个名字是不正确的。

     

在for-init语句中声明的6.5.3 / 1名称与条件中声明的名称在同一声明区域中

因此,我不再对为什么这是非法的C ++感到好奇。 :-)我只想把它编译好!

我看了G ++与语言方言相关的选项。根据{{​​3}},

  

如果指定了-ffor-scope,则在a中声明变量的范围    for-init-statement 仅限于‘for’循环本身,如指定的那样   按C ++标准。如果指定了-fno-for-scope,则范围为。{1}}   在 for-init-statement 中声明的变量扩展到了   封闭范围,与旧版本的G ++和其他版本一样   (传统)C ++的实现。

这是我能找到的唯一一个远程相关的声音选项。奇怪的是,将-fno-for-scope传递给g++会使示例编译;即使使用-Wall -Wextra也没有任何警告。但是,回到我想编译的代码,这个选项会产生很多错误,因为在 for-init-statement 中初始化的变量现在扩展了范围。显然,这不是解决方案。

只是为了澄清:我不打算用C ++编译器编译C99代码,这是愚蠢的。我有一些C ++代码; git blame告诉重新声明的行是2001年的。我想编译一个标记为2011年发布的提交,因此,我认为它当时没有被破坏。

如果不进行修改,我可以做些什么来编译?目前,我选择了一个重命名违规变量的提交,但我更愿意将CXXFLAGS中的内容传递给configure。更一般地说,g++为什么(或确实)-fno-for-scope有这种行为和重新声明?

编辑:好吧,可能我应该更加明确。事实上我有一些2001年的代码形式,今天就被打破只是为了设置一些背景。当然,存储库的当前master编译时没有任何编译器技巧。但是,我感兴趣的是我如何使g++在历史上表现得像,因为有一个压倒性的概率,即有问题的提交被标记,g++接受了这种代码。

EDIT2:在使用-fdump-tree-original之后,问题基本上变成了:是否有任何C ++标准或非标准C ++实现(在GCC中,最好是)在for-init-statement中声明的变量与循环体或周围代码的范围不同?

0 个答案:

没有答案