首頁 > 後端開發 > C++ > 為什麼為複雜變數賦值會導致 C 程式中的無限循環,即使它看起來像是一個看似無害的操作?

為什麼為複雜變數賦值會導致 C 程式中的無限循環,即使它看起來像是一個看似無害的操作?

Linda Hamilton
發布: 2024-10-30 04:29:02
原創
185 人瀏覽過

Why does assigning a value to a complex variable cause an infinite loop in a C   program, even though it appears to be a seemingly innocuous action?

具有不可預測循環行為的C 編譯謎題

以下程式碼提出了一個有趣的編譯問題:

<code class="c++">#include <iostream>
#include <complex>
using namespace std;

int main() {
    complex<int> delta;
    complex<int> mc[4] = {0};

    for(int di = 0; di < 4; di++, delta = mc[di]) {
        cout << di << endl;
    }

    return 0;
}</code>
登入後複製

相反當預期輸出「0, 1, 2, 3」終止時,程式碼會產生「0, 1, 2, 3, 4, 5, ...」的無限重複。經調查,比較 di < 1。 4 無法正常工作,導致無限循環。

停用看似無害的賦值 delta = mc[di] 神奇地修復了問題,產生預期的輸出。這個簡單的操作會導致什麼問題?

深入研究未定義的行為

解開這個謎團的關鍵在於理解未定義的行為。賦值 delta = mc[di] 會在循環的最後一次迭代中觸發對數組的越界訪問。雖然許多編譯器可能根據最佳化策略假設沒有未定義的行為,但這種假設本質上是有缺陷的。

開啟最佳化的 GCC 可以在假設不存在未定義行為的情況下積極優化循環。這種最佳化導致錯誤的推斷:di

因此,循環變成無限循環,因為條件 di

揭開編譯器的內部運作方式

仔細檢查最佳化後的程式碼顯示 di

與此行為相反,帶有 -fsanitize=undefined 的 Clang 會捕捉這種情況。然而,具有相同標誌的 GCC 在此特定實例中無法發出警告。

未定義行為的危險

未定義行為,由 C 標準定義,允許出現不可預測的結果,包括完全無視情況。應不惜一切代價避免未定義的行為,因為它可能導致編譯器不一致和意外的執行時間行為。

為了避免此類陷阱,程式設計師應該努力編寫符合預期語意的定義良好的程式碼。編譯器也應該實施適當的防禦措施,以提醒開發人員潛在的未定義行為。

以上是為什麼為複雜變數賦值會導致 C 程式中的無限循環,即使它看起來像是一個看似無害的操作?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板