[英]Why can I not do arithmetic on a cast of a void pointer?
void foo(void *ptr, int numBytes)
{
(char*)ptr += numBytes;
}
這不能在C中編譯。我知道替代方案。 但為什么這不起作用? 問題是什么?
問題
問題是(char*)ptr
不會產生左值 ,這意味着該值無法修改 - 可以將其視為轉換的臨時結果,轉換將產生類型為char*
的右值 。
它在語義上與您擁有以下示例相同,轉換產生臨時值,這樣的值不能分配新值。
int x = 123;
(float)x += 0.12f; /* (1), illegal */
/* ^-- sementically equivalent to `123.f += 0.12f` */
解
在你的問題中你已經聲明你已經知道這個問題的解決方法,但我想明確寫出解決方案,以顯示即使在強制轉換產生不可修改的值時,如何修改ptr
值。
void*
是char*
類型一樣
*((char**)&ptr) += numbytes; // make `ptr` move forward `numbytes`
( 注意 :當取消引用指針時,你得到一個左值 ,否則就不可能改變指向存儲在指針中的地址的指向值的值。)
在=
的左側,您需要一個lvalue
。 但是(char*)ptr
不是左值。
那是因為
(char*)ptr
不是左值。
試試這個:
void foo(void *ptr, int numBytes)
{
char* p = (char*)ptr;
p += numBytes;
}
更新
有關各種值類型的簡要說明,請訪問cppreference.com 。 這談到了C ++中的值類型,但核心思想轉化為C語言。
出於本次討論的目的,
左值是一個表達式,用於標識非臨時對象或非成員函數。
您可以獲取左值的地址並分配給不同的值。
例:
int i;
int* p = &i;
i = 20;
相反,
prvalue(“純”rvalue)是標識臨時對象(或其子對象)的表達式,或者是與任何對象無關的值。
字面值42
是右值。 你做不到:
int* p = &42;
42 = 53;
在這一行中,
char* p = (char*)ptr;
從(char*)ptr
創建左值( p
)。 因此,可以使用:
p += numBytes;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.