英特尔C&x2B+;编译器错误?(指针别名) 我使用英特尔C++编译器12,并在一个类似于下面的程序中工作,这是非常简单和直接的。while循环应该在第一次运行时停止。但是,当我使用英特尔编译器的/O2标志构建代码时,while循环从未停止过。如果禁用优化,或者使用VisualC++,则循环正常退出。如果我将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; } #包括 使用名称空间std; 结构段{ int i; int标志; }; int main(int argc,字符**argv) { p段; p、 i=0; p、 flag=1; para*pt=&p; cout

英特尔C&x2B+;编译器错误?(指针别名) 我使用英特尔C++编译器12,并在一个类似于下面的程序中工作,这是非常简单和直接的。while循环应该在第一次运行时停止。但是,当我使用英特尔编译器的/O2标志构建代码时,while循环从未停止过。如果禁用优化,或者使用VisualC++,则循环正常退出。如果我将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; } #包括 使用名称空间std; 结构段{ int i; int标志; }; int main(int argc,字符**argv) { p段; p、 i=0; p、 flag=1; para*pt=&p; cout,c++,compiler-construction,intel,C++,Compiler Construction,Intel,这是一种已知的情况。您有一个变量p和一个指针pt,它指向与p相同的东西。如果编译器可以假设只有一个“名称”,则可以使用许多优化对于给定变量,编译器的/O2可能会启用此假设。例如,编译器可以在循环期间将p的所有成员变量保留在寄存器中,这显然无法通过内存指针访问 查看您的编译器文档,了解如何告诉它不要假设没有指针别名。这可能是编译器开关或#pragma在GCC 4.7.1的MinGW下编译得很好。循环也结束了。+1正是我想到的想法。虽然代码没有违反严格的别名,但ICC似乎是ex我认为这里的情况是指针

这是一种已知的情况。您有一个变量
p
和一个指针
pt
,它指向与
p
相同的东西。如果编译器可以假设只有一个“名称”,则可以使用许多优化对于给定变量,编译器的
/O2
可能会启用此假设。例如,编译器可以在循环期间将
p
的所有成员变量保留在寄存器中,这显然无法通过内存指针访问


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

在GCC 4.7.1的MinGW下编译得很好。循环也结束了。+1正是我想到的想法。虽然代码没有违反严格的别名,但ICC似乎是ex我认为这里的情况是指针别名处理中的一个编译器错误,我不会把它归为编译器错误。这更像是“不要这样写”。您通过传递指针使代码更加复杂,编译器将无法猜测任何内容。边缘的确切位置永远无法确定。应用程序代码不应是编译器测试。@KirillKobelev:“编译器错误”这不是意见的问题。代码具有定义良好的语义,而创建的可执行文件与它们不匹配。这可能看起来像奇怪的代码,但在现实生活中会发生这样的事情。例如,当从库实例化模板时,生成的代码来自两个独立工作的不同作者。@KirillKobelev:我可以定义这条规则;你从错误的角度看它。编译器忽略别名永远都不好。它要么证明没有别名,要么假设有。它可能永远不会假设没有别名。
#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;
}