HOW TO:偵錯最佳化程式碼
更新:2007 年 11 月
這個主題適用於:
版本 |
Visual Basic |
C# |
C++ |
Web Developer |
---|---|---|---|---|
Express 版 |
![]() |
![]() |
僅適用原生 |
![]() |
Standard 版 |
![]() |
![]() |
僅適用原生 |
![]() |
Pro/Team 版 |
![]() |
![]() |
僅適用原生 |
![]() |
表格圖例:
![]() |
套用 |
![]() |
不套用 |
![]() |
預設隱藏的命令。 |
![]() |
---|
根據目前使用的設定與版本,您所看到的對話方塊與功能表命令可能會與 [說明] 中所描述的不同。若要變更設定,請從 [工具] 功能表中選擇 [匯入和匯出設定]。如需詳細資訊,請參閱 Visual Studio 設定。 |
當編譯器最佳化程式碼時,它會重新調整位置和重新組織指令,產生較有效率的編譯程式碼。因為這種重新安排,偵錯工具不一定能辨識對應到一組指令的原始程式碼。
最佳化會影響:
區域變數,這些區域變數可能會由最佳化程式移除,或是移至偵錯工具不認識的位置。
函式內部的位置,這些位置在最佳化程式合併程式碼區塊時會變更。
呼叫堆疊上之框架的函式名稱,這個名稱在最佳化程式合併兩個函式時可能會出錯。
不過,假設所有框架都有符號,您在呼叫堆疊上看見的框架幾乎一定是正確的。如果您有堆疊損毀、以組件語言撰寫的函式,或是呼叫堆疊上的作業系統框架沒有相符的符號時,呼叫堆疊上的框架就會出錯。
全域變數和靜態變數一定會正確顯示,結構配置也會。如果您有結構的指標,而且指標的值是正確的,則結構的每個成員變數都會顯示正確的值。
由於這些限制,您應該盡可能地使用程式的非最佳化版本來進行偵錯。根據預設,最佳化在 Visual C++ 程式的 [偵錯] 組態是關閉的,而在 [發行] 組態是啟動的。
然而,有時錯誤可能只出現在程式的最佳化版本裡。在這種情況下,您必須偵錯最佳化程式碼。
若要啟動偵錯組建組態的最佳化
當您建立新專案時,選取 [Win32 Debug] 目標。在您完成程式的偵錯,並準備好建置 Win32 Release 目標以前,請使用 [Win32Debug] 目標。編譯器不會最佳化 [Win32 Debug] 目標。
在 [方案總管] 中選取專案。
在 [檢視] 功能表上按一下 [屬性頁]。
在 [屬性頁] 對話方塊裡,確定在 [組態] 下拉式清單方塊裡選取 [Debug]。
在左邊的資料夾檢視裡,選取 C/C++ 資料夾。
在 C++ 資料夾底下,選取 [Optimization]。
在右邊的屬性清單裡,尋找 [Optimization]。旁邊的設定可能是 [Disabled (/Od)]。從其他項目 (Minimum Size(/O1)、Maximum Speed(/O2)、Full Optimization(/Ox) 或 Custom) 中選擇一個項目。
如果您選擇 [Optimization] 的 [Custom] 選項,現在就可以為其他顯示在屬性清單裡的任一屬性設定其選項。
偵錯最佳化程式碼時,檢視 [反組譯碼] 視窗來查看哪些指令已經確實建立和執行。設定中斷點時,您必須了解中斷點可能會隨著指令移動。例如,請參考下列程式碼:
for (x=0; x<10; x++)
假設您在這行設定中斷點。您可以預期中斷點會叫用 10 次,但是如果程式碼已完成最佳化,便只會叫用中斷點一次。這是因為第一個指令會將 x 的值設為 0。編譯器會辨識這個動作只需做一次,並且將它移出迴圈 (Loop) 外。中斷點會隨著移動。
迴圈內部則仍保留比較和累加 x 的指令。當您檢視 [反組譯碼] 視窗時,為取得更佳控制,步驟單位會自動設為 [指令],這在逐步執行最佳化程式碼時很有用。