[英]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.