2012-10-30 37 views
4

鑑於此代碼:解決C++「分配的對象不是一個真正的左值」的錯誤

void FrMemCopy(void *to, const void *from, size_t sz) 
{ 
    size_t sz8 = sz >> 3; 
    size_t sz1 = sz - (sz8 << 3); 

    while (sz8-- != 0) { 
     *((double *)to)++ = *((double *)from)++; 
    } 

    while (sz1-- != 0) { 
     *((char *)to)++ = *((char *)from)++; 
    } 
} 

我收到的2線while環內target of assignment not really an lvalue警告。

任何人都可以分解這些線?

一個演員然後增加?

什麼是最簡單的寫法?

錯誤是什麼意思?

+4

簡單的方法是的memcpy(於從,SZ ) – stark

+2

代碼試圖通過使用'double'來一次複製8個字節,而不是一次只複製一個字節。代碼存在多個問題。它假定地址是8字節對齊的。然後它用表情快速鬆弛。坦率地說,你會用'的memmove()'或'的memcpy()'做的更好,但如果你必須發揮這種方式(並且可以與地址對齊約束,或總線錯誤或表現欠佳生活,當你得到的約束錯) ,那麼現在有幾個答案看起來好像他們做對了。 –

+0

@Jonathan,謝謝,這是有益的 – Jason

回答

0

您正在對LValue(賦值運算符的左側值)執行遞增操作。按照邏輯和定義,LValue必須始終是一個變量。它不能是一個常數。當你正在執行一個增量操作時,它會在左邊留下一個給你錯誤的常量值。

4

它不喜歡*((char*)to)++聲明。

試試這個:

void FrMemCopy(void *to, const void *from, size_t sz) 
{ 
    size_t sz8 = sz >> 3; 
    size_t sz1 = sz - (sz8 << 3); 
    double * tod = (double *) to; 
    double * fromd = (double *) from; 
    while (sz8-- != 0) { 
     *(tod++) = *(fromd++); 
    } 

    char * toc = (char *) tod; 
    char * fromc = (char *) fromd; 
    while (sz1-- != 0) { 
     *(toc++) = *(fromc++); 
    } 
} 
+0

你可以解釋一下爲什麼抱怨的'(字符*)以++'? – Jason

+1

它會抱怨'(char *)to ++',因爲你不能增加一個'void *'。它實際上抱怨'*((char *)to)++'因爲'(char *)to'不是左值;這是鑄造一個本身不是左值的左值表達式的結果。 –

+1

您在第二個循環中使用了錯誤的地址 - 它需要從第一個循環停止的地方複製,而不是從初始地址複製。 –

1

我試圖把它改寫的方式,沒有出現警告:

void FrMemCopy(void *to, const void *from, size_t sz) 
{ 
    size_t sz8 = sz >> 3; 
    size_t sz1 = sz - (sz8 << 3); 

    double *xto = (double *)to; 
    double *xfrom = (double *)from; 
    while (sz8-- != 0) { 
     *xto++ = *xfrom++; 
    } 

    char *cto = (char *)to; 
    char *cfrom = (char *)from; 
    while (sz1-- != 0) { 
     *cto++ = *cfrom++; 
    } 
} 
2

不能應用++到鑄件的結果,只有一個左值(一個變量)。所以,你需要用適當類型的增量創建新的變量:

void FrMemCopy(void *to, const void *from, size_t sz) 
{ 
    size_t sz8 = sz >> 3; 
    size_t sz1 = sz - (sz8 << 3); 

    double *to1 = (double *)to; 
    double *from1 = (double *)from 
    while (sz8-- != 0) { 
     *to1++ = *from1++; 
    } 

    char *to2 = (char *)to1; 
    char *from2 = (char *)from1; 
    while (sz1-- != 0) { 
     *to2++ = *from2++; 
    } 
} 
1

顯式類型轉換的結果是右值在這種情況下 - 根據C++ 11標準5.4.1。您不能將increment operator應用於右值,它應爲左值。詳情請參閱C++ value category

使用臨時變量來獲得所需的效果:不要嘗試了微優化的編譯器/庫:

double* to_dbl = static_cast<double*>(to); 
double* from_dbl = static_cast<double*>(from); 

while(sz8-- != 0) 
{ 
    *(to_dbl++) = *(from_dbl++); 
} 
0

首先回答我只想說之前。編譯器編寫者將贏得100次之中的99次。根據您正在複製和需要的類型,使用std::copymemcpy

其他答案指出,你可以用臨時變量解決即時編譯錯誤。

我沒有在任何情況下建議做這下面,但我相信你可以通過強制轉換爲引用類型實現這一點:

void FrMemCopy(void *to, const void *from, size_t sz) 
{ 
    size_t sz8 = sz >> 3; 
    size_t sz1 = sz - (sz8 << 3); 

    while (sz8-- != 0) { 
     *((double *&)to)++ = *((double *&)from)++; 
    } 

    while (sz1-- != 0) { 
     *((char *&)to)++ = *((char *&)from)++; 
    } 
} 
相關問題