[英]Why does the IAR compiler get stuck?
在我的嵌入式項目中,使用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中編譯得很好。我想念一些東西嗎? 為什么這段代碼不能編譯?
* 注意:提供的代碼是實際代碼的摘錄,在邏輯上毫無意義。
更新:代碼使用“高”/“平衡”優化級別進行編譯。 使用較低的優化級別,編譯結束就好了。
當使用“高”級別但在“啟用的轉換:”框中刪除優化選項時,它也會卡住。 此外,卡住“速度”和“大小”選項。
優化是任何編譯器中最復雜的部分,因此最有可能成為編譯器錯誤的地方 - 特別是對於具有小型開發團隊的“窄市場”編譯器,如果是桌面系統編譯器的用戶,則編號較小。
優化的應用有兩個你需要警惕的后果; 編譯器本身可能有錯誤(在這個實例中似乎很可能),並且您自己的代碼中的任何“未定義行為”區域可能會改變優化下的行為。 如果需要使用優化,則需要准備進行廣泛測試 - 生成的代碼不一定等同於調試/開發構建。
在這種情況下,您當然應該向供應商報告該問題,理想情況是使用真正可編譯的示例和項目配置。 要解決您的直接問題,明智地使用volatile
關鍵字可以解決問題 - 優化器將努力消除看似無效的變量 - 如果您可以避免優化器采用相同的路徑,則可以避免該錯誤。 如果您沒有正確使用volatile
,那么在任何情況下, 您的代碼都可能會出現錯誤 。 在您的示例中,某些變量當然需要聲明為volatile,但由於示例不是“真實的”而是“說明性的”,因此無法提供建議。
作為解決方法的另一種可能性是有選擇地禁用此代碼段或源文件的優化。 您真的需要優化才能使您的代碼完全正常工作嗎? 如果不是,我建議在任何情況下避免它 - 不使用優化避免調試和發布代碼之間的行為變化,並使調試在第一個實例中更簡單。 我建議使用優化作為代碼大小或性能相關問題的解決方案,當它們出現時,如果它們出現,而不僅僅是理所當然。
如果編譯器字面上“卡住”,即凍結,所以你必須殺死進程,那么這當然是編譯器錯誤。
弄清楚為什么一段代碼(=編譯器)我們沒有看到特定輸入的中斷是非常困難的。
另一方面,如果你的意思是編譯器停止,因為它報告了代碼中的錯誤,那么當然知道它以及它所說的內容是有用的。
我懷疑這是一個編譯器錯誤。 考慮向編譯器供應商提交錯誤,並確保附加錯誤的源代碼,以便他們可以重現編譯器錯誤。 祝你好運。 現在嘗試解決這個bug。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.