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

标签 c++ compiler-construction intel

我正在使用英特尔 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 被修改吗?

顺便说一句:谁能告诉我如何使用英特尔编译器在 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;
}

最佳答案

这种情况称为 pointer aliasing .您有一个变量 p 和一个指向与 p 相同的对象的指针 pt。如果编译器可以假定给定变量只有一个“名称”,则可以使用许多优化,并且编译器的 /O2 可以启用这一假设。例如,编译器可以在循环期间将 p 的所有成员变量保存在寄存器中,这显然不能通过内存指针访问。

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

关于c++ - 英特尔 C++ 编译器错误? (指针别名),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12240246/

相关文章:

c# - 为什么编译器决定 2.3 是 double 而不是十进制?

opencl - 使用 Intel Core 2 Duo E8500 CPU 的 CL_DEVICE_NOT_AVAILABLE

c++ - 使用 intel 编译器编译 DLL 时出错

c - 32 位英特尔堆栈帧格式字符串利用

java - 使用 ANativeWindow_lock 返回错误 -22 与 android Gstreamer SDK

c++ - Perlin Noise 在 Y 轴上得到错误的值 (C++)

c++ - 检查 DLL 是否已经注册

c++ - std::pair 中的模板模板参数

javascript - Jquery *编译器*可能吗?

compiler-construction - GNU Bison : Syntax Error, 意外 <token>