I have the following variables:
char *p;
int l=65;
Why do the following casts fail?
(int *)p=&l;
and:
The problem is that when you're performing the casts (aside from whether or not the kind of casting you're doing is a good idea or not) is that the cast expression results in an rvalue.
rvalues cannot be assigned to or have their addreses taken.
The correct way to do this would be:
int I = 65;
char* p = (char*)&I;
&I
gives you an int*
that points to I
; you then cast this to a char*
and assign it to p
.
Note that you shouldn't ordinarily cast between pointers of unrelated types. A char*
can be used to access any object, though, so in this particular case it is safe.
(int *)p=&l;
The line above doesn't work, because as soon as you cast p
to (int*)
, the result is an anonymous temporary object, which is an rvalue and not an lvalue; consquently, the result cannot receive the assignment, and even if the language did allow it, you'd be assigning to a temporary casted copy of p
, not to the original p
.
p=&((char) l);
The line above does not work for a similar reason; the result of (char) l
is a temporary object that is a copy of l
casted to the type char. Consequently, because it is temporary, you cannot take its address.
Insead, you can use:
p = (char*) &l
The result of type conversion is always an rvalue. Rvalue cannot be assigned to, which is why your first expression doesn't compile. Rvalue cannot be taken address of, which is why your second expression doesn't compile.
In order to perform the correct type conversion, you have to to it as follows
p = (char *) &l;
This is the proper way to do what you tried to do in your second expression. It converts int *
pointer to char *
type.
Your first expression is beyond repair. You can do
*(int **) &p = &l;
but what it does in the end is not really a conversion, but rather reinterpretation of the memory occupied by char *
pointer as int *
pointer. It is an ugly illegal hack that most of the time has very little practical value.
In plain C, which is not that strict to type conversions, this code would compile and actually work. On a C++ compiler it would actually require explicit casts as already mentioned (see other answers).