共用方式為


偵錯優化程式碼

本文說明要設定哪些編譯器開關,使您能更有效地偵錯優化的程式碼。

從 Visual Studio 2022 17.14 版開始有較佳的體驗,可讓您偵錯優化程式代碼,就像編譯未優化一樣,同時保留優化程式代碼的速度。 如需詳細資訊,請參閱 C++ 動態偵錯 (預覽)

備註

您看到的對話框和功能表命令可能會與您使用中的設定或版本而定,說明中所述的對話框和功能表命令可能會有所不同。 若要變更您的設定,請選擇 [[工具] 功能表上的 [匯入和導出設定]。 如需詳細資訊,請參閱 重設所有設定

備註

/Zo (增強優化偵錯的編譯器選項) 編譯器選項(於 Visual Studio Update 3 中引入)會為優化過的程式碼產生更豐富的除錯資訊(未使用 /Od 編譯器選項建置的專案)。 請參閱 /O 選項 (優化程序代碼)]。 這包括改善對局部變數和內嵌函式偵錯的支援。

使用 /Zo 編譯程式選項 時,會停用 [編輯後繼續]。

當編譯程式優化程序代碼時,它會重新置放並重新組織指令。 這會產生更有效率的編譯程序代碼。 由於此重新排列,調試程式不一定會識別對應至一組指令的原始程式碼。

優化可能會影響:

  • 優化工具可以移除局部變數,或將它們移至調試程式無法瞭解的位置。

  • 當優化器合併代碼區塊時,函式內的位置會被改變。

  • 呼叫堆疊上框架的函式名稱,如果優化器合併兩個函式,則可能是錯誤的。

    假設您擁有所有框架的符號,您在呼叫堆棧上看到的框架幾乎一律正確。 如果您有堆疊損毀、以組合語言撰寫的函式,或在呼叫堆疊上有作業系統框架沒有相符符號,則呼叫堆疊上的框架會出錯。

    全域和靜態變數一律會正確顯示。 結構配置也是如此。 如果您有結構的指標,而且指標的值正確,則結構的每個成員變數都會顯示正確的值。

    由於這些限制,您應該盡可能使用未優化版本的程序進行偵錯。 根據預設,優化會在C++程式的 [偵錯] 組態中關閉,並在 [發行] 組態中開啟。

    不過,Bug 可能只會出現在程式的優化版本中。 在此情況下,您必須對優化程式代碼進行偵錯。

在偵錯組態中開啟優化

  1. 當您建立新專案時,請選取 Win32 Debug 目標。 使用 Win32 Debug 目標,直到程式完全偵錯完畢,且您已準備好建置 Win32 Release 目標。 編譯程式不會優化 Win32 Debug 目標。

  2. 在 [方案總管] 中選取專案。

  3. [檢視] 選單上,單擊 [屬性頁]

  4. 在 [屬性頁] 對話框中,確定已在 [組態] 下拉式清單中選取 Debug

  5. 在左側的資料夾檢視中,選取 C/C++ 資料夾。

  6. 在 [C++] 資料夾底下,選取 [Optimization]。

  7. 在右邊的屬性清單中,尋找 Optimization。 旁邊的設定可能表示 Disabled (/Od)。 選擇其他其中一個選項(Minimum Size``(/O1)Maximum Speed``(/O2)Full Optimization``(/Ox)Custom)。

  8. 如果您選擇 [Optimization] 的 [Custom] 選項,您現在可以為屬性清單中顯示的任何其他屬性設定選項。

  9. 選取 [項目屬性] 頁面的 [組態屬性]、[C/C++]、[命令行] 節點,然後將 (/Zo) 新增至 [其他選項] 文本框。

    警告

    新增 /Zo 會停用 編輯及繼續

    當您除錯優化過的程式碼時,請使用 [反組譯] 視窗來查看哪些指令已建立和執行。 當您設定斷點時,您必須知道斷點可能會與指令一起移動。 例如,請考慮下列程式代碼:

for (x=0; x<10; x++)

假設您在這一行設定斷點。 您可能會預期斷點會觸發 10 次,但如果程式碼已經優化,斷點只會被觸發一次。 這是因為第一個指令會將 x 的值設定為 0。 編譯程式會辨識這只需要完成一次,並將它移出迴圈。 斷點會隨著它移動。 比較和遞增 x 的指示會保留在迴圈內。 當您檢視 [反組譯碼] 視窗時,步驟單元 會自動設定為指令,以取得更大的控制權,這在逐步執行優化程序代碼時很有用。