I need some advice with this strange behavior – lets have this code:
int ** p;
This compiles without any trouble:
p++;
But this:
((int**)p)++;
Gives me this error message: “error: lvalue required as increment operand”
.
I am casting to p
to the type it already is, nothing changes, so what is the problem? This is simplified version of problem I came across, when I was trying to compile one old
version of gdb
. So I suppose, that this worked and something changed. Any idea what is wrong with the second example?
lvalue:- lvalue simply means an object that has an identifiable location in memory (i.e. having an address). In any assignment statement “lvalue” must have the capability to store the data.
In C, you don't need to cast the return value of malloc . The pointer to void returned by malloc is automagically converted to the correct type. However, if you want your code to compile with a C++ compiler, a cast is needed.
Declaration for malloc: void *malloc(size_t *size*); In C it is not mandatory to cast a void pointer to any other pointers, but in C++ is must.
Casting the result of malloc() to the appropriate pointer type enables the compiler to catch subsequent inadvertent pointer conversions. When allocating individual objects, the "appropriate pointer type" is a pointer to the type argument in the sizeof expression passed to malloc() .
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.
When you typecast an expression, the result of that expression is an rvalue rather than an lvalue. Intuitively, a typecast says "give me the value that this expression would have if it had some other type," so typecasting a variable to its own type still produces an rvalue and not an lvalue. Consequently, it's not legal to apply the ++
operator to the result of a typecast, since ++
requires an lvalue and you're providing an rvalue.
That said, it is in principle possible to redefine the C language so that casting a value to its own type produces an lvalue if the original expression is an lvalue, but for simplicity's and consistency's sake I suppose the language designers didn't do this.
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With