nunojpg nunojpg - 1 year ago 103
C++ Question

Pointer arithmetic ignored by the compiler

I'm compiling the following with -O0 (recent gcc/clang) and they both give me a answer I don't expect.

#include <iostream>

struct xy{
int x,y;

int main()
xy a{1,2};

int x{1};
int y{2};

int *ptr1=&a.x;
int *ptr2=&x;

ptr1++; // I now point to a.y!
(*ptr1)++; // I now incremented a.y to 3

ptr2++; // I now point to y!
(*ptr2)++; // I now incremented y to 3

std::cout << "a.y=" << a.y << " ptr1=" << *ptr1 << '\n';
std::cout << "y= " << y << " ptr2=" << *ptr2 << '\n';


a.y=3 ptr1=3
y= 2 ptr2=2

So this access with pointers to non-class variables is being optimized-out by the compiler.

I also tried to mark the int and int* as volatile, but it didn't make any difference.

What part of the standard am I missing / why is the compiler allowed to do this?

Coliru snippet at:

Answer Source

In the first case dealing with class members the part you are ignoring is the compiler is allowed to add any amount of padding in between members of a object and at the end of the object. Because of this increment a pointer to one member does not have to give you the next member.

The second part of the standard you are missing is it is illegal to access memory though a pointer to what it doesn't point to. Even though y might be there in memory the pointer is not allowed to access it. It is allowed to access x and it is allowed to compare to see if it one past x but it cannot dereference that one past x address.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download