Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intel C++ compiler bug? (pointers aliasing)

I am using Intel C++ compiler 12.0, and working on a program similar to the following, which is very simple and straightforward. The while loop should stop in the first run. However, when I build the code using /O2 flag with the Intel compiler, the while loop never stops. If I disable the optimization, or use visual C++, the loop exits normally. If I change pt->flag to p.flag, which I suppose is the same thing, the loop exits normally too. I think it has something to do with Intel's optimization. Is this a bug in the Intel compiler? or I missed something here?

#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;
}

Updates: Thanks for everybody's answer. I am confused by the explanation of "pointer aliasing". If p is in the registers and pt can't access it, why the following code will break the while loop with the intel compiler? Firstly "pt->flag = 0;" should never take effect because i=0. Secondly even if it's in effect, shouldn't "pointer aliasing" prevent p being modified?

BTW: Can anybody let me know how to turn on/off the pointer aliasing in Visual Studio with intel compiler? Thanks!

#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;
}
like image 846
Dan Xu Avatar asked Sep 02 '12 22:09

Dan Xu


People also ask

What is pointer aliasing in C?

Pointer aliasing is a hidden kind of data dependency that can occur in C, C++, or any other language that uses pointers for array addresses in arithmetic operations. Array data identified by pointers in C can overlap, because the C language puts very few restrictions on pointers.

Is there aliasing in C?

In C, C++, and some other programming languages, the term aliasing refers to a situation where two different expressions or symbols refer to the same object. When references access that object in different ways—as both reads and stores—there are consequences for the order in which these mixed accesses can happen.

What is arm pointer aliasing?

If a function has two pointers pa and pb , with the same value, we say the pointers alias each other. This introduces constraints on the order of instruction execution. If two write accesses that alias occur in program order, they must happen in the same order on the processor and cannot be re-ordered.

What is aliasing in programming?

An alias occurs when different variables point directly or indirectly to a single area of storage. Aliasing refers to assumptions made during optimization about which variables can point to or occupy the same storage area.


1 Answers

This is a situation known as pointer aliasing. You have a variable p and a pointer pt that points to the same thing as p. Many optimisations can be used if the compiler can assume that there is only one "name" for a given variable, and /O2 for your compiler may enable this assumption. For example, the compiler could keep all the member variables for p in registers during the loop, which obviously can't be accessed through a memory pointer.

Check your compiler documentation to find out how to tell it to not assume there are no pointer aliases. This could be a compiler switch or a #pragma.

like image 118
Greg Hewgill Avatar answered Sep 21 '22 21:09

Greg Hewgill