簡體   English   中英

為什么我不能對void指針的強制轉換進行算術運算?

[英]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值。

  1. 指針的地址變為void
  2. 將此地址轉換為指向char的指針
  3. 取消引用指針,產生指向char指針
  4. 修改此yield 左值 ,就好像原始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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM