簡體   English   中英

英特爾C ++編譯器錯誤? (指針別名)

[英]Intel C++ compiler bug? (pointers aliasing)

我正在使用英特爾C ++編譯器12.0,並且正在開發類似於以下的程序,這非常簡單明了。 while循環應該在第一次運行時停止。 但是,當我使用英特爾編譯器使用/ O2標志構建代碼時,while循環永遠不會停止。 如果我禁用優化,或使用visual C ++,循環將正常退出。 如果我將pt-> flag更改為p.flag,我認為這是相同的,循環也會正常退出。 我認為這與英特爾的優化有關。 這是英特爾編譯器中的錯誤嗎? 或者我錯過了什么?

#include <iostream>

using namespace std;

struct para {
    int i;  
    int flag;
};

int main(int argc, char **argv)
{
    para p;
    p.i = 0;
    p.flag = 1;

    para * pt = &p;
    cout << "loop started" << endl;

    int i;
    while (p.flag) {
        if (p.i == 0) {
            for (i=0; i<1; i++) {
                if (p.flag != 1)
                    break;
            }
            if (i==1) {
                pt->flag = 0;
            }
        }
    }
    cout << "loop stopped" << endl;
    return 1;
}

更新:感謝大家的回答。 我對“指針別名”的解釋感到困惑。 如果p在寄存器中並且pt無法訪問它,為什么以下代碼將使用intel編譯器中斷while循環? 首先“pt-> flag = 0;” 因為i = 0,所以永遠不會生效。 其次,即使它有效,不應該“指針別名”阻止p被修改?

順便說一句:任何人都可以告訴我如何使用intel編譯器打開/關閉Visual Studio中的指針別名? 謝謝!

#include <iostream>
using namespace std;
struct para {
    int i;  
    int flag;
};

int main(int argc, char **argv)
{
    para p;
    p.i = 0;
    p.flag = 1;

    para * pt = &p;
    cout << "loop started" << endl;

    int i=0;
    while (p.flag) {
        if (p.i == 0) {
            //for (i=0; i<1; i++) {
            //  if (p.flag != 1)
            //      break;
            //}
            if (i==1) {
                pt->flag = 0;
            }
        }
    }
    cout << "loop stopped" << endl;
    return 1;
}

這是一種稱為指針別名的情況 你有一個變量p和指針pt指向同樣的事情, p 如果編譯器可以假定給定變量只有一個“名稱”,並且編譯器的/O2可以啟用此假設,則可以使用許多優化。 例如,編譯器可以在循環期間將p所有成員變量保留在寄存器中,這顯然不能通過內存指針訪問。

檢查編譯器文檔以了解如何告訴它不要假設沒有指針別名。 這可以是編譯器開關或#pragma

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM