web-dev-qa-db-ja.com

c ++ memcpyの戻り値

http://en.cppreference.com/w/cpp/string/byte/memcpy c ++のmemcpyは、宛先、ソース、サイズ/バイトの3つのパラメーターを取ります。また、ポインタを返します。どうしてこんなことに?データを入力およびコピーするのに十分なパラメータではありません。

または私は何かを誤解していますか?例では戻り値を使用していません

31
knittl

関数に返すものがない場合は、入力パラメーターの1つ(primary 1と見なされるパラメーター)を返すのが通例です。これを行うと、式で「連鎖」関数呼び出しを使用できます。たとえば、あなたはすることができます

char buffer[1024];
strcat(strcpy(buffer, "Hello"), " World");

具体的には、strcpyが元のdst値を結果として返すためです。基本的に、このような関数を設計するときは、「チェーン」に最も適切なパラメーターを選択して、結果として返すことができます(ここでも、他に返すものがない場合、つまり、関数がvoidを返す場合)。

好きな人もいれば嫌いな人もいます。それは個人的な好みの問題です。 C標準ライブラリは、多くの場合、この手法をサポートしています。memcpyは別の例です。考えられるユースケースは、

char *clone_buffer(const char *buffer, size_t size)
{
   return memcpy(new char[size], buffer, size);
}

memcpyが宛先バッファポインタを返さなかった場合、おそらく上記を次のように実装する必要があります。

char *clone_buffer(const char *buffer, size_t size)
{
   char *clone = new char[size];
   memcpy(clone, buffer, size);
   return clone;
}

「長く」見えます。これら2つの実装の効率に違いがある理由はありません。そして、どちらのバージョンがより読みやすいかは議論の余地があります。それでも多くの人は、上記の最初のバージョンのような簡潔なワンライナーを書く「無料の」機会を高く評価するかもしれません。

関数からポインタを返すことは、通常(または常に)関数がメモリを割り当て/再割り当てする可能性があることを示すはずであるという一般的な信念があるため、memcpyが宛先バッファポインタを返すことを混乱させることがよくあります。これはmight確かに後者を示していますが、そのような厳格なルールはなく、かつてないため、ポインタを返すことは(memcpyのように)どういうわけか「間違っている」または「悪い習慣」であるという意見がよく表明されますまったく根拠がありません。

55
AnT

IIRC、Cの初期バージョンでは、voidリターンはありませんでした。したがって、十分に長い間使用されてきたライブラリ関数は、レガシーの理由でsomethingを返しますが、これは彼らが思いつくことができる最高のものでした。

_string.h_には、宛先パラメーターmemcpystrcpystrcatを返す関数がたくさんあります。あまり便利ではありませんが、害はありません(おそらく、多くの呼び出し規約では、実装するための命令さえ必要ありません)。

おそらく、char *nextbuf = memcpy(get_next_buf(), previous_buf+offset, previous_size-offset);の代わりにchar *nextbuf = get_next_buf(); memcpy(nextbuf, etc);などの使用法を思い付くかもしれません。

比較のために、qsortはvoidを返します。 「何かを返す、それは役に立つかもしれない」という原則に基づいてbaseを返すように定義できたかもしれませんが、そうではありませんでした。 _std::copy_は、出力範囲のendにイテレータを返す方が便利です。呼び出し元が計算するのが簡単ではない、または不可能でさえある可能性がある非ランダムアクセスイテレータの場合。

11
Steve Jessop

値を返すことにより、memcpy関数の呼び出しをr値として使用できます。

1

リターンを使用していないことを示したい場合は、リターンをボイドにキャストできます。例:
(void) memcpy(mydest, mysrc, mybytes);

0
mike jones
void* memcpy( void* dest, const void* src, std::size_t count );
returns void * which can be assigned to another void array that can be used as  
int or char data type.
void * ret = new int[6];
ret = memcpy(newarr,arr,sizeof(int)* 5);
0
Pratap