Ist die Erinnerung an eine Konstruktion oder Zuordnung eines trivial kopierbaren Typs?

Nehmen wir an, Sie haben ein Objekt vom TypT und ein passend ausgerichteter Speicherpufferalignas(T) unsigned char[sizeof(T)]. Wenn du benutztstd::memcpy aus dem Objekt vom Typ @ kopierT zumunsigned chararray, wird das als Kopierkonstruktion oder Kopierzuweisung angesehen?

Wenn ein Typ trivial kopierbar ist, aber kein Standardlayout, ist es denkbar, dass eine Klasse wie diese:

struct Meow
{
    int x;
protected: // different access-specifier means not standard-layout
    int y;
};

könnte so implementiert werden, da der Compiler nicht gezwungen ist, das Standard-Layout zu verwenden:

struct Meow_internal
{
private:
    ptrdiff_t x_offset;
    ptrdiff_t y_offset;
    unsigned char buffer[sizeof(int) * 2 + ANY_CONSTANT];
};

Der Compiler könnte @ speichex undy von Meow innerhalb des Puffers an einem beliebigen Teil vonbuffer, möglicherweise sogar zufällig versetzt innerhalb vonbuffer, solange sie richtig ausgerichtet sind und sich nicht überlappen. Der Offset vonx undy kann sogar bei jeder Konstruktion zufällig variieren, wenn der Compiler dies wünscht. x könnte nach @ gehy wenn der Compiler dies wünscht, da der Standard nur Mitglieder desselben Zugriffsspezifizierers benötigt, um in Reihenfolge zu gehen, undx undy haben unterschiedliche Zugangsdaten.)

Dies würde die Anforderungen erfüllen, trivial kopierbar zu sein; einmemcpy würde die ausgeblendeten Versatzfelder kopieren, damit die neue Kopie funktioniert. Aber manche Dinge würden nicht funktionieren. Zum Beispiel einen Zeiger auf @ haltx über einmemcpy würde brechen:

Meow a;
a.x = 2;
a.y = 4;
int *px = &a.x;

Meow b;
b.x = 3;
b.y = 9;
std::memcpy(&a, &b, sizeof(a));

++*px; // kaboom

Ist es dem Compiler jedoch wirklich erlaubt, eine trivial kopierbare Klasse auf diese Weise zu implementieren? Dereferenzierungpx s, sollte nur undefiniertes Verhalten sein, wenna.xie Lebensdauer von @ ist abgelaufen. Hat es? Die relevanten Teile des Normentwurfs für N3797 sind zu diesem Thema nicht sehr klar. Dies ist Abschnitt [basic.life] / 1:

DasLebenszei eines Objekts ist eine Runtime-Eigenschaft des Objekts. Ein Objekt soll eine nicht triviale Initialisierung haben, wenn es von einem Klassen- oder Aggregattyp ist und es oder eines seiner Mitglieder von einem anderen Konstruktor als einem trivialen Standardkonstruktor initialisiert wird. Hinweis -Initialisierung durch einen einfachen Konstruktor zum Kopieren / Verschieben ist keine triviale Initialisierung. -end note] Die Lebensdauer eines Objekts vom TypT beginnt wann:

Speicher mit der richtigen Ausrichtung und Größe für TypT wird erhalten undwenn das Objekt nicht trivial initialisiert wurde, ist die Initialisierung abgeschlossen.

Die Lebensdauer eines Objekts vom TypT endet wenn:

wennT ist ein Klassentyp mit einem nicht trivialen Destruktor [class.dtor]), der Destruktoraufruf startet oderder Speicher, den das Objekt belegt, wird wiederverwendet oder freigegeben.

Und das ist [basic.types] / 3:

Für jedes Objekt (mit Ausnahme eines Basisklassen-Unterobjekts) vom einfach kopierbaren TypT, ob das Objekt einen gültigen Wert vom Typ @ enthält oder nicT, die zugrunde liegenden Bytes [intro.memory]), aus denen das Objekt besteht, kann in ein Array von @ kopiert werdchar oderunsigned char. Wenn der Inhalt des Arrays vonchar oderunsigned charird @ wieder in das Objekt kopiert, behält das Objekt anschließend seinen ursprünglichen Wert.Beispiel weggelassen

Die Frage wird dann, ist einmemcpy Überschreiben einer trivial kopierbaren Klasseninstanz "Copy Construction" oder "Copy Assignment"? Die Antwort auf die Frage scheint zu entscheiden, obMeow_internal ist eine gültige Möglichkeit für einen Compiler, eine einfach kopierbare Klasse zu implementieren.Meow.

Wennmemcpy ist "Kopie Konstruktion", dann ist die Antwort, dassMeow_internal ist gültig, da die Kopierkonstruktion den Speicher wieder verwendet. Wennmemcpy ist "Kopierzuweisung", dann lautet die Antwort:Meow_internal ist keine gültige Implementierung, da durch die Zuweisung keine Zeiger auf die instanziierten Member einer Klasse ungültig werden. Wennmemcpy ist beides, ich habe keine Ahnung, wie die Antwort lautet.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage