私は Intel C++ コンパイラ 12.0 を使用しており、次のような非常にシンプルでわかりやすいプログラムを作成しています。while ループは、最初の実行で停止する必要があります。しかし、Intel コンパイラで /O2 フラグを使用してコードをビルドすると、while ループが停止しません。最適化を無効にするか、ビジュアル C++ を使用すると、ループは正常に終了します。pt->flag を p.flag に変更すると、同じことだと思いますが、ループも正常に終了します。Intelの最適化と関係があると思います。これは Intel コンパイラのバグですか? または私はここで何かを逃した?
#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;
}