samedi 28 mars 2015

Swapping `std::aligned_storage` instances containing non-trivially-copyable types - undefined behavior?


Vote count:

0




ideone link



#include <iostream>
#include <type_traits>
using namespace std;

// Non-trivially-copyable type.
struct NTC
{
int x;
NTC(int mX) : x(mX) { }
~NTC() { cout << "boop." << x << endl; }
};

int main()
{
using AS = aligned_storage_t<sizeof(NTC), alignof(NTC)>;

// Create two `std::aligned_storage` instances
// and "fill" them with two "placement-new-constructed"
// `NTC` instances.
AS as1, as2;
new (&as1) NTC{2};
new (&as2) NTC{5};

// Swap the `aligned_storages`, not their contents.
std::swap(as1, as2);

// Explicitly call `~NTC()` on the contents of the
// aligned storage instances.
NTC& in1{*static_cast<NTC*>(static_cast<void*>(&as1))};
NTC& in2{*static_cast<NTC*>(static_cast<void*>(&as2))};
in1.~NTC();
in2.~NTC();

return 0;
}




Is the above code undefined behavior?


Here's what I think that's happening:



  • NTC is a non-trivially-copyable type.

  • I'm creating two memory locations suitable to store NTC objects (std::aligned_storage).

  • I construct two NTC instances directly into the memory locations.

  • std::aligned_storage instances are PODTypes.

    This means the type is compatible with the types used in the C programming language, can be manipulated using C library functions: it can be created with std::malloc, it can be copied with std::memmove, etc, and can be exchanged with C libraries directly, in its binary form.




  • Since the aligned storage instances are POD types, I should be allowed to move/swap/copy them around.

  • Swapping the aligned storage instances means take all the bytes from aligned storage A and swap them with all the bytes from aligned storage B.

  • Doing so will not call the destructor/copy-constructor of the internally stored NTC objects.


Are any of my points incorrect? If undefined behavior does occur, in what part of the program does it occur? And why?

asked 17 secs ago







Swapping `std::aligned_storage` instances containing non-trivially-copyable types - undefined behavior?

Aucun commentaire:

Enregistrer un commentaire