4

このコードを考えると:

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)++;
    }
}

ループtarget of assignment not really an lvalue内の 2 行で警告が表示されwhileます。

誰かがそれらの線を打破できますか?

キャストしてからインクリメント?

それを書くためのより簡単な方法は何ですか?

エラーの意味は何ですか?

4

6 に答える 6

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++);
    }
}
于 2012-10-30T16:51:55.497 に答える
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++;
    }
}
于 2012-10-30T16:55:37.530 に答える
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++;
    }
}
于 2012-10-30T16:53:37.340 に答える
1

この場合、明示的な型変換の結果は右辺値です。C++11 標準の 5.4.1 に従っています。インクリメント演算子を右辺値に適用することはできません。左辺値でなければなりません。詳細については、 C++ 値カテゴリを参照してください。

必要な効果を得るために一時変数を使用します。

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

while(sz8-- != 0)
{
    *(to_dbl++) = *(from_dbl++);
}
于 2012-10-30T16:57:33.197 に答える
0

最初に答える前に、私に言わせてください:コンパイラ/ライブラリをマイクロ最適化しようとしないでください。コンパイラの作成者は、100回のうち99回のようなものを獲得します。コピーするタイプと必要なタイプに応じて、std::copyまたは使用します。memcpy

他の回答では、一時変数を使用して即時コンパイルエラーを解決できると述べています。

いかなる状況でもこれを行うことはお勧めしませんが、参照型にキャストすることでこれを達成できると思います。

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)++;
    }
}
于 2012-10-30T17:38:29.200 に答える
0

LValue (代入演算子の左側の値) に対してインクリメント操作を実行しています。論理的にも定義上も、LValue は常に変数でなければなりません。定数にすることはできません。インクリメント操作を実行すると、左側に定数値が残り、エラーが発生します。

于 2012-10-30T16:49:15.313 に答える