[英]Is typecasting on lvalue of operation not allowed?
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指针的类型转换,并尝试分配char地址。
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;
Yes, you cannot cast the left operand of the assignment operator in C. 是的, 您不能在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);
}
The cast on lvalue is valid, ie, (void *)ptr
itself is valid, but it's not an lvalue anymore. 左值上的强制转换有效,即(void *)ptr
本身有效,但它不再是左值。 This is called lvalue conversion . 这称为左值转换 。
The fix, as @Joachim commented: 正如@Joachim评论的那样:
ptr = (int *) &a;
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. 可能会给它在小端机器上工作的印象(现在大部分时间),但依赖于字节后面&a
为空。 Which it's not the case. 事实并非如此。
I would suggest 我会建议
printf("%d\n", (int)a) ;
type cast of of a variable or expression results in r-value. 变量或表达式的类型转换导致r值。 so (void *)ptr gives r-value and you are trying to allocate &a to r-value. so(void *)ptr给出了r值,你试图将&a分配给r值。 it is something like 0x12345=&a which is wrong so you are getting l-value is required. 它是像0x12345 =&a这是错误的,所以你需要l值。
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];
}
EDIT : this answer only works in C++, not C, but might be relevant nevertheless. 编辑 :这个答案只适用于C ++,而不是C,但可能仍然相关。
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 * . 注意& 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 . 但是,在这种特殊情况下,printf行为仍然是未定义的,因为您将char重新解释为int,即使您假设为小端,在字节表示10之后仍可能有3个未定义的字节。
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 eg 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: 这很有用,例如当您在CUDA或嵌入式设备上对数组进行跨步循环时,您希望提前缓存准确的步骤以避免每次在循环内乘以4:
const int stride = sizeof(int)*step;
int *my_ptr = first_ptr;
for (int i = 0; i < count; ++i) {
...
(char *&)my_ptr += stride;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.