在我的嵌入式项目中,使用 IAR EWARM 开发工具(v7.10.3),我有以下代码:
/* 1 */ uint32_t packet_sync = 0;
/* 2 */ uint32_t synced = 0;
/* 3 */ uint32_t gpio = 0;
/* 4 */ while (1) {
/* 5 */ if ((packet_sync != 0) && ((packet_sync = gpio) == 0)) {
/* 6 */ if (synced < 2) {
/* 7 */ synced++;
/* 8 */ }
/* 9 */ }
/* 10 */ };
由于某些原因,当我编译代码时,编译器会在编译过程中卡住。我尝试使用各种构造,似乎我做了任何微小的改变,消除了问题(但也可能使代码不正确)。例如,在#6a中添加NOP,代码 成功编译:
/* 6 */ if (synced < 2) {
/* 6a */ __NOP();
/* 7 */ synced++;
/* 8 */ }
成功更改的其他示例是删除第7行或将第5行更改为:
/* 5 */ if ((packet_sync != 0) && ((gpio) == 0)) {
以及更多变种。
我没有在有问题的代码中看到C规则违规,并且它在Visual Studio 2013中编译得很好。我会错过什么吗?为什么这段代码不能编译?
* 注意:显示的代码是实际代码的摘录,在逻辑上毫无意义。
更新:代码使用&#34;高&#34; /&#34;平衡&#34;优化水平。对于较低的优化级别,编译结束就好了。
使用&#34; High&#34;它也会卡住。等级,但删除了&#34;启用转换中的优化选项:&#34;框。此外,坚持&#34;速度&#34;和&#34;尺寸&#34;选项。
答案 0 :(得分:3)
优化是任何编译器中最复杂的部分,因此也是编译器错误的最有可能的地方 - 特别是对于具有小型开发团队的“狭义市场”编译器,如果是桌面系统编译器的用户,则编号较小。
优化的应用有两个你需要警惕的后果;编译器本身可能有错误(在这个实例中似乎很可能),并且您自己的代码中的任何“未定义行为”区域可能会改变优化下的行为。如果需要使用优化,则需要做好充分测试的准备 - 生成的代码不一定等同于调试/开发构建。
在这种情况下,您当然应该向供应商报告该问题,理想情况下应该使用真正可编译的示例和项目配置。要明确解决您的问题,明智地使用volatile
关键字可以解决问题 - 优化工作人员会努力消除看似没有效果的变量 - 如果您可以避免优化器采取相同的路径,您可以避免错误。如果您未正确使用volatile
,则your code may well exhibit bugs在任何情况下都会进行优化。在您的示例中,某些变量当然需要声明为volatile,但由于示例不是“真实的”而是“说明性的”,因此无法提供建议。
作为解决方法的另一种可能性是有选择地禁用此代码段或源文件的优化。您真的需要优化才能使您的代码完全正常工作吗?如果不是,我建议在任何情况下避免它 - 不使用优化避免调试和发布代码之间的行为变化,并使调试在第一个实例中更简单。我建议使用优化作为代码大小或性能相关问题的解决方案,当它们出现时,而不仅仅是理所当然的。
答案 1 :(得分:2)
如果编译器字面上“卡住”,即冻结,所以你必须杀死进程,那当然是编译器错误。
弄清楚为什么一段代码(=编译器)我们没有看到特定输入的中断是非常困难的。
另一方面,如果你的意思是编译器停止了,因为它报告了你的代码中的错误,那么当然知道它及其说的内容是有用的。
答案 2 :(得分:2)
我怀疑这是一个编译错误。考虑向编译器供应商提交错误,并确保附加错误的源代码,以便他们可以重现编译器错误。祝你好运。现在尝试解决这个问题。