Reputation: 531
I have the below code, where i am doing a type cast of integer pointer to void pointer and try to assign char address.
void main()
{
int *ptr;
char a = 10;
(void *)ptr = &a;
printf("%d\n", *ptr);
}
I am getting below error, Is there anyway that i can fix this?
error: lvalue required as left operand of assignment
(void *)ptr = &a;
Upvotes: 2
Views: 3054
Reputation: 131
Sorry to be 8 years late to this discussion, but I came across it because I have a similar problem and have found a solution in C. The issue arises because, as others have said, a cast like (void *)ptr
does not result in an lvalue so you cannot assign to it. But a dereferenced pointer like *(void **)&ptr
is an lvalue. So you could change your code to:
void main()
{
int *ptr;
char a = 10;
*(void **)&ptr = &a;
printf("%d\n", *ptr);
}
and this compiles and runs OK, and does what I think you want it to do. It gives odd output because the value output comes partly from uninitialised bytes adjacent to the char a
variable, so it's a dangerous thing to do, but it is valid C.
Modified code compiling and running here
Upvotes: 0
Reputation: 518
EDIT: this answer only works in C++, not C, but might be relevant nevertheless.
You have to cast your lvalue to a reference-to-a-pointer instead of a pointer, and then the assignment will work:
void main()
{
int *ptr;
char a = 10;
(void *&)ptr = &a;
printf("%d\n", *ptr);
}
Note the & after void * . This way you preserve its lvalue-ness and you can assign into it.
However, in this particular case the printf behaviour will still be undefined because you are reinterpreting a char as an int, and even if you assume little endian, you may still have 3 undefined bytes after the byte representing 10.
A better use case:
int a[5];
int *ptr = a + 2; // points to the element with index=2
(char *&)ptr += sizeof(int); // advances the pointer to the next element
This is useful e.g. when you are doing a strided for-loop over an array in CUDA or on an embedded device, and you want to cache the exact step in advance to avoid multiplication by 4 every time inside the loop:
const int stride = sizeof(int)*step;
int *my_ptr = first_ptr;
for (int i = 0; i < count; ++i) {
...
(char *&)my_ptr += stride;
}
Upvotes: 0
Reputation:
The question doesn't match your example - but the answer to your question (instead of your example) - is yes - you can. Here's how:
void encode_fixed32(char *buffer,float input) {
((float *)buffer)[0]=input;
}
void decode_fixed32(char *buffer) {
return ((float *)buffer)[0];
}
Upvotes: 0
Reputation: 21
type cast of of a variable or expression results in r-value. so (void *)ptr gives r-value and you are trying to allocate &a to r-value. it is something like 0x12345=&a which is wrong so you are getting l-value is required.
Upvotes: 1
Reputation: 5230
ptr = (int *)&a ;
is more natural but it's not portable. Might give the impression it works on little endian machine (most nowadays) but relies on byte after &a
being null. Which it's not the case.
I would suggest
printf("%d\n", (int)a) ;
Upvotes: 4
Reputation: 24344
Yes, you cannot cast the left operand of the assignment operator in C.
Also, in your case you could just do it the other way to make your code work:
void main()
{
int *ptr;
char a = 10;
ptr = (int*) &a; // this is perfectly fine
printf("%d\n", *ptr);
}
Upvotes: 3
Reputation: 122423
The cast on lvalue is valid, i.e, (void *)ptr
itself is valid, but it's not an lvalue anymore. This is called lvalue conversion.
The fix, as @Joachim commented:
ptr = (int *) &a;
Upvotes: 3