標準のレイアウトタイプのレイアウト要件が、コピー可能なタイプにも適用されないコンパイラはありますか?特に、型へのポインタがその最初のメンバへのポインタであるという批判的なルール(基本クラスは派生クラスの前に来ると考えられる)です。つまり、型のアドレスはその基本型と同じアドレスになります。些細なことは常に擬似標準レイアウトにコピーできますか?
コードでは、次のコードが実際には動作しない一般的なコンパイラはありますか?それは私の常識のように思えるので、C++ 11では標準化されていなかったことに驚きました。
struct base { int a; /* is a trivial class*/ };
struct derived : public base { int b; /*still a trivial class*/ }
void copy(base * a, base * b, size_t len)
{
memcpy(a, b, len);
}
...
derived d1, d2;
copy(&d1, &d2, sizeof(derived));
私は確かにこれはGCCで働く、と私は(私が間違っているかもしれませんが)、それはMSVCで働くと信じて知っています。非歴史的なコンパイラでは、上記は意図したとおりに動作しませんか?
拡張例
上記の例では、根本的な問題を示しているが、そこに一つになるだろう意図を示さないことができます。ここには少し冗長な例があります。本質的に誰もがメッセージをキューに入れる "send"を呼び出すことができます。そして、後で何かが実際のタイプにキャストすることによって各メッセージをディスパッチします。
struct header { int len, id; }
struct derived : public header { int other, fields; }
void send(header * msg)
{
char * buffer = get_suitably_aligned_buffer(msg->len);
memcpy(buffer, msg, msg->len);
}
void dispatch(char * buffer)
{
header * msg = static_cast<header*>(buffer);
if(msg->id == derived_id)
handle_derived(static_cast<derived*>(msg));
}
derived d;
d.len = sizeof(d);
d.id = deirved_id;
send(&d);
...
char * buffer = get_the_buffer_again();
dispatch(buffer);
まだ多くの側面は省略していますが、重要な部分が示されています。
C++では 'memcpy'オブジェクトは「一般的な」ものだと思いますか? –
なぜ私は代入演算子を使うだけで他のことをやってもらえないのですか?私はかなり多くのコードでそれを見てきたので、C++でmemcpyを見ることはめったにありません。 – 111111
@ LightnessRacesinOrbitさらに、標準は 'memcpy'オブジェクトの規則を提供しますが、この正確な場合を保証するものではありません。 –