我有一些代码将一堆TNotifyEvents放在一个vector中。
std::vector<TNotifyEvent> m_availableCallbacks;
这是应用程序的主要形式的成员。在表单构造函数中,它填充了事件。
m_availableCallbacks.push_back(ReadoutLastValue);
m_availableCallbacks.push_back(ReadoutCurrentDay);
m_availableCallbacks.push_back(ReadoutLastDay);
m_availableCallbacks.push_back(Readout7Days);
m_availableCallbacks.push_back(Readout1Month);
m_availableCallbacks.push_back(ReadoutChooseTimeSpan);
m_availableCallbacks.push_back(ReadoutAllData);
然后迭代此向量并用于创建弹出菜单并将通知事件分配给该弹出菜单中的元素。
在本地编译它没有问题。当我在构建服务器上编译它(运行TeamCity 6.5)时,我在等于第二个push_back调用的行上得到一个内部编译器错误。
我尝试通过编辑cbproj文件在构建代理上本地禁用智能缓存预编译标头。这产生了成功的构建。所以我从所有cbproj文件中删除了使用智能缓存预编译头文件的指令并提交了更改。我告诉TeamCity进行一次干净结帐,但我再次在同一个地方遇到了相同的内部编译器错误。奇怪的是,在失败的编译成功后运行新的编译,所以这感觉非常随机。
到底是怎么回事?我习惯于在其他 C++ 编译器中传递函数指针(由我自己创建)就好了。TNotifyEvents的内部处理是否损坏或编译器只是不稳定且容易损坏?
查看其他采用TNotifyEvents的代码,它们不适用于引用或指针,所以我没有尝试。而且由于代码(当它编译时)按预期工作,这似乎不是问题。
更新:
我可以补充一点,TeamCity的日志显示 FrontEnd.cpp 文件(包含此代码)在我重新运行编译并且成功时被跳过。
[10:04:37]: [MakeObjs] CallTarget
[10:04:37]: [CallTarget] _CppDepCheck
[10:04:44]: [_CppDepCheck] MessageMap
[10:04:44]: [MessageMap] Skipping: ..., FrontEnd.cpp, ...
如果发生内部编译器错误,编译必须成功。否则它怎么可能跳过编译文件而仍然神奇地出现并以编译的形式使用?:)
更新2
经过调查,我可以确认这仅在以发布模式编译时发生。在发布时,它甚至发生在 IDE 中的本地机器上。我试过摆弄像这样的设置
- 禁用所有优化
- 生成最快的代码
- 外部类型文件
- 等等
在每次尝试之间清理构建。但 ICE 并没有消失。然而,我确实设法让它抱怨另一个文件中的另一个位置。将设置设置回之前的状态不会使错误返回到FrontEnd.cpp文件。这个编译器感觉有点不稳定:)
事实上,我开始得到 ICE 的所有代码,并且必须重新启动 IDE 才能编译任何东西。