首页 文章

英特尔C编译器错误? (指针别名)

提问于
浏览
8

我正在使用英特尔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;
}

1 回答

  • 6

    这种情况称为pointer aliasing . 你有一个变量 p 和一个指针 pt ,指向与 p 相同的东西 . 如果编译器可以假定给定变量只有一个"name",并且编译器的 /O2 可以启用此假设,则可以使用许多优化 . 例如,编译器可以在循环期间将 p 的所有成员变量保留在寄存器中,这显然无法通过内存指针访问 .

    检查编译器文档以了解如何告诉它不要假设没有指针别名 . 这可以是编译器开关或 #pragma .

相关问题