16

I have the following variables:

char *p;
int l=65;

Why do the following casts fail?

(int *)p=&l;

and:

p=&((char) l);
1
  • What, exactly, did you mean by 'did not work'? Commented Apr 29, 2010 at 0:08

5 Answers 5

27

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.

Sign up to request clarification or add additional context in comments.

3 Comments

hey idont understand your typing (int **) ,,,,what meaning has (int **)
Pointer-to-pointer. As stated in that answer, it's just an ugly trick.
@AndreyT I would not call that an trick or a hack. Ugly YES but it is necessary in embedded programming! It is the only way to actually force a known address of a register, normally defined as 0xE000ED28 (for the Cortex M3 CFSR register), to be an LVALUE! Atmel's definition for the Cortex M3 CFSR register is (*(uint32_t*)0xE000ED28). It is necessary (so not a hack), but definitely UGLY. Could you please add a little information about this in your answer?
6

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.

2 Comments

Specifically, according to C99 6.3.2.3.7, the behaviour of converting a pointer of one type to a pointer of a different type is undefined only if the pointers in question have different alignments. It continues to say that when a pointer to an object is converted to a pointer to character type, the result points to the lowest addressed byte of the object.
@dreamlax: Actually, I was thinking of C99 §6.5/7, which details the aliasing rules. Converting pointers may not lead to undefined results, but accessing the pointed to object might.
3

(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

Comments

0

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.

Comments

-1

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).

3 Comments

No, it doesn't work in plain C either. The result of a cast operator is just like the result of + - you can't do &((char)l) for the same reason you can't do &(a + b).
Hm. I don't know why, but msvs2008 compiles this code and the debug shows that it actually works. Strange.
@CostantinoRupert: Greetings from 8 years in the future! Perhaps msvs2008 allows casts as lvalues as a language extension. It's definitely invalid in "plain C".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.