Kopieren von std::aligned_storage::type definiert?
-
Anhand folgendem Beispiel sieht man, dass es *möglich* ist eine Instanz von std::aligned_storage::type zu kopieren, ohne den verwalteten Speicher explizit zu kopieren. Anfangs dachte ich, dass sich std::aligned_storage::type äquivalent zu char[N] verhalten würde, das implizierte Kopieren also nicht möglich sei.
#include <iostream> #include <type_traits> #include <cstring> int main() { typename std::aligned_storage<sizeof(char) * 64, alignof(char)>::type m; typename std::aligned_storage<sizeof(char) * 64, alignof(char)>::type n; std::memcpy(&m, "Hello World", 12); std::cout << reinterpret_cast<const char*>(&m) << std::endl; n = m; // HIER std::cout << reinterpret_cast<const char*>(&n) << std::endl; std::memcpy(&m, "123456", 7); std::cout << reinterpret_cast<const char*>(&m) << std::endl; std::cout << reinterpret_cast<const char*>(&n) << std::endl; return 0; }Resultat: http://ideone.com/42WVPY
Ist das Kopieren eines std::aligned_storage undefiniertes Verhalten (in obigem Fall also nur Zufall, dass das erwartete Ergebnis eintrifft) oder korrekt?
Ich sehe gerade, dass type ein struct ist, welches den Speicher kapselt. Nutze ich bei der Zuweisung "n = m" nun also den default operator=() dieses anonymen structs?
template<std::size_t Len, std::size_t Align> struct aligned_storage { typedef struct { alignas(Align) unsigned char data[Len]; } type; };
-
Gute Frage.
Der C++ Standard sagt nur, dass der Typ ein "POD type" ist. Ein "POD type" ist entweder ein "scalar type", ein "POD class", ein Array von solchen Typen sowie cv-qualifizierte Versionen davon. [§3.9/9]
Weil hier ein Array erlaubt ist, heißt das also, dass du dich nicht darauf verlassen kannst, dass das Ding kopierbar oder zuweisbar ist. Undefiniert ist das Verhalten hier nicht. Aber es ist nicht garantiert, dass Dein Code compiliert, weil ja ein rohes Array keinen Zuweisungsoperator bietet, z.B.
Andererseits wird in einer Bemerkung erwähnt, dass eine "typische Implementierung" hier ein "POD class"-Typ verwendet. [§20.9.7.6/1]
Das ist also ein bisschen unterspezifiziert.
-
Danke für die aufschlussreiche Antwort.
Ich denke, dass ich trotz der Möglichkeit weiterhin von der "einfachen Zuweisung" Gebrauch machen werde. Ist schlicht und ergreifend lesbarer. Falls mir mal ein Compiler mit abweichender Implementierung in die Finger kommen sollte, habe ich ja dann immer noch die Option den verwalteten Speicher explizit via memcpy zu kopieren.Noch einmal vielen Dank, krümelkacker.
