【问题标题】:Visual C++ 6 Variable Scope BugVisual C++ 6 变量范围错误
【发布时间】:2016-04-02 11:57:31
【问题描述】:

所以我继承了一些和我一样古老的代码,我的任务是维护它。该代码是使用 Visual C++ 6 编写的,因此无论想象如何,它都不是现代的。

无论如何,我决定尝试升级该解决方案(或者我猜微软当时称它为工作区),以便我可以将它与 Visual Studio 2013 一起使用并使用有点现代的 IDE(我想我宁愿使用 Emacs或 VC++ 6 上的普通记事本)。 After having changed the character set for the MFC library,我收到一大堆 undeclared identifier 错误(大约 1100 个错误)。其中很多似乎源于一个临时变量范围问题,这让我想知道这个代码之前是如何被允许编译的。我看到很多这样的东西:

void MyClass::MyFunc() 
{
    for(int i=0;i<56;i++)
    {
      // do some stuff
    } 

    // command hardware
    for(i=0;i<m_pinfo->vc_num;i++)
    {
      // do some more stuff
    }
}

奇迹般地,这段代码在 VC++ 6 中编译得很好,但(谢天谢地)在 VS 2013 中编译得很好。注意变量 i 是如何在第一个 for 循环的范围内声明的,但它随后在第二个for 循环。这种代码在整个程序中随处可见。

使用 VC++ 6 的 Goto Definition 工具,它告诉我变量 i(但它仍然可以编译!)和几个看似不相关的变量和参数“i”之间存在歧义在单独的 .cpp 文件中,其中一些甚至在结构中定义。

这里会发生什么?出于所有意图和目的,我看不到这段代码是如何在 VC++6 中编译的。

【问题讨论】:

  • 这可以追溯到标准之前的日子。微软选择继续支持这个(现在是非标准的)范围,你可以通过编译器开关来改变它。
  • 恶心,我不敢相信有人认为这是个好主意,导致代码非常混乱。
  • 我认为这样做的“目的”是能够检查循环是否定期完成,或者是因为 break 语句。 (循环后if(i == end) ..
  • 嗯,仍然是一个非常糟糕的方式来做 IMO。但我知道什么,我只是个年轻人
  • 请注意,即使 vc++6 实际上也可以通过 /Za 开关在这方面符合标准。不幸的是,它无法编译自己的头文件,所以这纯粹是一个学术观点。

标签: c++ visual-c++ visual-studio-2013 scope mfc


【解决方案1】:

它是 MSVC++ 6 中的扩展。根据标准,在 for 循环中声明的变量不能在 for 循环范围之外访问。如果您需要在 MSVS 上的较新版本中获得这种非标准行为,那么您可以Enable the /Zc:forScope flag

我建议您修复 for 循环,以便获得符合标准的代码。这样不知道这个扩展存在的人不会对代码感到惊讶。

【讨论】:

  • 嗯,我正在争论是否要这样做或只是修复代码以符合要求。诚然,在 2013 年尝试编译时,我遇到了一大堆其他看似无关的错误。
  • @audiFanatic 我个人会将代码修复为符合标准。我只会在无法更新的情况下使用旗帜(预算原因,发货日期,邪恶的老板)。
  • 不是真的错误/非标准扩展。只是遵守预标准化规范。这是 C++ 的原始行为,但后来意识到这是一个错误,并且对于第一个标准,行为发生了变化。然而,微软已经有很多客户使用旧行为编写代码 - 所以他们坚持使用它。
  • @MartinBonner:为了公平对待微软,他们没有坚持下去。他们做了一个开关,后来又切换了默认值。
  • 是的。我认为 MS 的行为完全合理。
【解决方案2】:

在旧 C 中,您可以定义 int 而无需指定其类型。我怀疑 VC++6 会遵守这条古老的规则,并为第二个循环隐式定义 new i 变量。

如果我是对的,这也应该编译:

void MyClass::MyFunc() 
{
    for(i=0;i<56;i++)
    {
      // do some stuff
    } 

    // command hardware
    for(i=0;i<m_pinfo->vc_num;i++)
    {
      // do some more stuff
    }
}

这应该打印1 2 3 4

void MyClass::MyFunc() 
{
    for(i=1;i<3;i++)
    {
      std::cout << i << ' ';
    } 

    // command hardware
    for(;i<5;i++)
    {
      std::cout << i << ' ';
    }
}

【讨论】:

  • 有趣的猜测,但错误。
猜你喜欢
  • 1970-01-01
  • 2017-10-30
  • 2013-11-18
  • 2014-02-13
  • 1970-01-01
  • 1970-01-01
  • 2015-02-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多