I need some advice with this strange behavior – lets have this code:
int ** p;
This compiles without any trouble:
p++;
Old versions of gcc support something called "lvalue casts" -- if you cast something that is an lvalue the result is an lvalue and can be treated as such. The main use for it is allowing you to increment a pointer by an amount corresponding to a different size:
int *p;
++(char *)p; /* increment p by one byte, resulting in an unaligned pointer */
This extension was deprecated some time around gcc v3.0 and removed in gcc v4.0
To do the equivalent thing in more recent versions of gcc, you need do an addition and assignment (instead of an increment) casting the pointer to the type for the addition and back for the assignment:
p = (int *)((char *)p + 1);
Note that trying to dereference the pointer after this is undefined behavior, so don't count on it doing anything useful.