After posting one of my most controversial answers here, I dare to ask a few questions and eventually fill some gaps in my knowledge.
Why isn't an expression of the kind ((type_t *) x)
considered a valid lvalue, assuming that x
itself is a pointer and an lvalue, not just some expression?
I know many will say "the standard disallows it", but from a logical standpoint it seems reasonable. What is the reason that the standard disallows it? After all, any two pointers are of the same size and the pointer type is just a compile-time abstraction that indicates the appropriate offset that should be applied when doing pointer arithmetic.
Note that if
x
is a pointer type,*(type_t **)&x
is an lvalue. However, accessing it as such except perhaps in very restricted circumstances invokes undefined behavior due to aliasing violations. The only time it might be legal is if the pointer types are corresponding signed/unsigned or void/char pointer types, but even then I'm doubtful.(type_t *)x
is not an lvalue, because(T)x
is never an lvalue, regardless of the typeT
or the expressionx
.(type_t *)
is just a special case of(T)
.From a top level, it would generally serve no purpose. Instead of '((type_t *) x) = ' one might as well go ahead and do 'x = ', assuming x is a pointer in your example. If one wishes to directly modify values pointed by the address 'x' but at the same time after interpreting it to be a pointer to a new data type then *((type_t **) &x) = is the way forward. Again ((type_t **) &x) = would serve no purpose, let alone the fact it is not a valid lvalue.
Also in cases of ((int *)x)++, where at least 'gcc' does not complain along the lines of 'lvalue' it could be reinterpreting it as 'x = (int *)x + 1'