vendredi 3 décembre 2021

Explanation std::aligned_storage and reinterpret cast

Could you please look at this lines of code taken from the cpp reference and translate them for me, explaining them line by line?

#include <iostream>
#include <type_traits>

struct A {  // non-POD type
  int avg;
  A (int a, int b) : avg((a+b)/2) {}
};

typedef std::aligned_storage<sizeof(A),alignof(A)>::type A_pod;

int main() {
  A_pod a,b;
  new (&a) A (10,20);
  b=a;
  std::cout << reinterpret_cast<A&>(b).avg << std::endl;

  return 0;
}

So this is my explanation.

  • First of all this class is non - POD because a non-trivial constructor is defined ( a user-defined constructor is non-trivial, at least I think).

  • this is starting to be a little more difficult to grasp: std::aligned_storage<sizeof(A), alignof(A)>type:: A_pod; is used to get an uninitialised, aligned block of memory. We need to provide the sizeof the object we want to store and the alignment using alignof(A) ( for instance we would need an align == 4, for char == 1, for float == 4, for short == 2, and so on ...).

  • With the line A_pod a, b; we are getting uninitialised blocks of memory;

  • new (&a) A (10, 20); Here placement new is used and only now we are actually constructing the object by providing the pointer to the block of memory just allocated.

  • b = a is probably the copy constructor and the content of block of memory a is going to be copied in block of memory b.

  • This is the part that I do not understand probably also because I almost never seen nor needed to really use reinterpret_cast. So here reinterpret cast is not doing any bit computation but is simply telling the compiler to treat b as a reference of type A, right?. My question is why do we need to do that. Probably just to access the member average but would not be way of accessing it with a?

  • Could someone also show some code using std::aligned_storage to understand it better, I looked up some other questions but just found probably three examples. I would also appreciate if you could give an explanation, and give a reason for the choice of aligned_storage.Thanks in advance.

P.S. could also someone tell me when to use an allocator to allocate uninitialised memory and when to use this approach?

Aucun commentaire:

Enregistrer un commentaire