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