3

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

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

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;
}

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

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

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

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

4

3 回答 3

1

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

if( m_ptr == NULL )

等价形式

if( !m_ptr )

一切都编译没有错误。

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

于 2015-05-05T03:51:45.517 回答
0

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

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

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

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

所以我玩Project->Options->Debugging settings关闭了这个:

  • 内联函数扩展 (-vi)

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

于 2022-02-24T09:55:11.433 回答
0

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

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

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

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

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

msbuild.exe Targets.xml /p:BCC_InlineFunctionExpansion=false /t:Build
于 2022-03-04T11:30:00.450 回答