【问题标题】:Internal compiler error in condition with bool property带有布尔属性的内部编译器错误
【发布时间】:2015-05-05 03:50:48
【问题描述】:

最近我遇到了一个奇怪的问题,一个简单的源不想编译。我在许多站点中寻找解决方案(和原因),但效果不佳(错误报告除外,但我没有找到直接原因)。

下面我提供简单的代码来重现这种情况:

struct Foo {
  Foo() : m_x( true ) {}
  __property bool x = { read=m_x };

  private:
    bool m_x;
};

template<typename T>
struct TMyPointer {
  T * m_ptr;
  TMyPointer( T * ptr ) : m_ptr( ptr ) {}
  ~TMyPointer()
  {
    delete m_ptr;
  }

  T * operator->() const
  {
    return Get();
  }

  T * Get() const
  {
    if( m_ptr == NULL )
      ; // some error handling

    return m_ptr;
  }
};

int _tmain(int argc, _TCHAR* argv[])
{
  TMyPointer<Foo> bar( new Foo );

  if( bar->x && 1 == 1 ) ; // Failed
  if( 1 == 1 && bar->x ) ; // OK
  if( !!bar->x && 1 == 1 ) ; // OK
  if( bar->x == true && 1 == 1 ) ; // OK
  if( (bar->x) && 1 == 1 ) ; // OK

  return 0;
}

编译器未能编译主函数内的第一个条件。什么其他等价条件的陌生编译就成功完成了。

这是我仅在发布编译期间的行为。为了重现,我使用了 Embarcadero® C++Builder® XE5 版本 19.0.13476.4176

错误信息:[bcc32 致命错误] File1.cpp(43): F1004 Internal 0x14470090 处的编译器错误,基数为 0x14410000

有人知道上面的例子有什么问题吗?也许是带有属性机制的使用模板?

【问题讨论】:

  • 应始终向编译器供应商/供应商报告 ICE。这意味着编译器认识到出了问题。根据定义,它不应该发生。供应商可能想要修复它,特别是如果您有一个小的干净复制品(MCVE (How to create a Minimal, Complete, and Verifiable Example?) 是 Stack Overflow 使用的术语)。他们最渴望在当前版本中修复它;由于您的编译器版本更古老,他们将不太热衷于修复它,除非它也会在当前版本中引起问题。
  • 只是好奇 - 你为什么要重新发明 std::auto_ptr/std::unique_ptr 而不是按原样使用它们?
  • @Remy Lebeau 是的,你说得对,但这并不取决于我。我在更大的团队中工作,该团队维护着相当旧的应用程序。许多机制是多年前编写的,并且多年来一直没有任何问题。最近团队的同事写了新功能导致编译问题。在调试时,我得出的结论是条件是原因。请记住,上面的代码只是重现这种情况的简单示例。我的同事当然知道存在智能指针,但我认为这与该主题无关 :)

标签: c++ c++builder c++builder-xe5


【解决方案1】:

在我的情况下是简单的解决方案,它似乎是 Get 方法内部的问题条件。当我改变时

if( m_ptr == NULL )

等价形式

if( !m_ptr )

一切编译都没有错误。

我在这里写它是因为我想分享我的见解 - 它可能对某人有所帮助。

【讨论】:

  • 正如其他人所说,您应该将此报告给 Embarcadero,以便他们了解此错误。如果没有,他们修复它的可能性不大。无论如何,他们肯定不会在 XE5(也不是 6,也不是 7)上修复任何东西,所以最好有一个解决方法,正如您所展示的那样。
【解决方案2】:

最近我得到了类似的 ICE(一旦我的源代码变大),您的解决方案似乎有一段时间有所帮助,但在代码中的一些小改动 ICE 再次出现后并没有真正起到帮助。基于我的问题的行为:

  • IDE:BDS2006 Turbo C++ 资源管理器(其 BCB 版本介于 BCB6 和 RAD 之间)
  • 庞大的 win32 项目(涉及 USB、OpenGL、CAD/CAM 的数 MBytes 代码)
  • 代码的每一部分都经过多年的测试,一旦它们在一起并且代码变得太大,就会出现可编译的可分离问题
  • 项目在第一次运行时编译良好,但之后任何重新编译都会失败

临时解决办法是关闭IDE,删除所有obj,tds,exe,...文件重新启动IDE并重新编译。

我假设编译器和/或 IDE 泄漏或覆盖了自身的某些部分,从而破坏了其功能。由于在 IDE 重新启动后问题仍然存在而不删除临时文件,我认为它与存储在其中的调试信息有关。

所以我玩了Project-&gt;Options-&gt;Debugging settings关闭这个:

  • 内联函数扩展 (-vi)

帮助(甚至不需要重新启动 IDE 或删除临时文件)。

【讨论】:

    【解决方案3】:

    没有足够的声誉来支持或评论其他人的帖子,但我最近找到了与@Spektre 回复中相同的解决方案。

    禁用内联函数扩展修复了我们多年来在随机项目中出现完全不相关的内部编译器错误的问题。我们只在 Release 配置中的 MSBUILD 脚本上体验过它们。

    我通过检查 Release 配置中与 Debug 配置不同的所有编译器选项并一一更改以匹配 发现了这一点通过 msbuild 参数为整个解决方案/项目组调试 配置。最后,当我禁用 内联函数扩展 选项时,它开始构建而没有任何错误。

    • 这些问题发生了,我在 C++ Builder XE5 上确认了修复;
    • 从我记事起,它就一直随机出现(Borland C++ 2006 及更高版本)
    • 老开发人员过去常常尝试恢复最新的提交,直到它再次开始编译......这在背后是一个痛苦。

    任何寻求将参数传递给 MSBUILD 命令(对于脚本中的所有目标)的解决方案的人都可以将此行添加到 msbuild.exe 调用中:

    msbuild.exe Targets.xml /p:BCC_InlineFunctionExpansion=false /t:Build
    

    【讨论】:

      猜你喜欢
      • 2021-06-18
      • 1970-01-01
      • 1970-01-01
      • 2011-08-26
      • 1970-01-01
      • 2010-11-08
      • 1970-01-01
      • 1970-01-01
      • 2011-02-20
      相关资源
      最近更新 更多