I need some advice with this strange behavior – lets have this code:
int ** p;
This compiles without any trouble:
p++;
In C language all conversions (including explicit casts) always produce rvalues. No exceptions. The fact that you are casting it to the same type does not make it exempt from that rule. (Actually, it would be strange to expect it to make such an inconsistent exception.)
In fact, one of fundamental properties of the entire C language is that it always converts lvalues to rvalues in expressions as quickly as possible. Lvalues in C expressions are like 115th element of Mendeleev table: they typically live a very short life, quickly decaying to rvalues. This is a major difference between C and C++, with the latter always attempting to preserve lvalues in expressions as long as possible (although in C++ this specific cast would also produce an rvalue).