Aliasing for optimizing small buffers using std :: aligned_union and std :: aligned_union

I was looking for optimizing a small implementation buffer for an object std::function.

Boost implements a small buffer for the boost::functionfollowing:

union function_buffer
{
    mutable void* obj_ptr;
    struct type_t {
      const detail::sp_typeinfo* type;
      bool const_qualified;
      bool volatile_qualified;
    } type;

    mutable void (*func_ptr)();

    struct bound_memfunc_ptr_t {
      void (X::*memfunc_ptr)(int);
      void* obj_ptr;
    } bound_memfunc_ptr;

    struct obj_ref_t {
      mutable void* obj_ptr;
      bool is_const_qualified;
      bool is_volatile_qualified;
    } obj_ref;

    // To relax aliasing constraints
    mutable char data;
  };

and performs the following actions:

new (reinterpret_cast<void*>(&out_buffer.data)) functor_type(*in_functor);

In addition, C ++ 11 provides std::aligned_unionand std::aligned_storagethat are suitable for this . The first gives a type:

suitable for use as an uninitialized storage for any object whose size is no more Lenand whose alignment is a dividerAlign

I would have a desire to use something like:

class MyFunction {
private:
  typename std::aligned_storage<something>::type buffer;
  MyFunctionVtable* vtable; 
public:
  template<class F>
  MyFunction(F f)
  {
    static_assert(sizeof(F) <= sizeof(buffer) &&
      alignof(F) <= alignof(buffer), "Type not suitable");
    new (&buffer) F(std::move(f));
    vtable = ...;
  }
  // [...]
};

Does this (or the implementation of the raise) not violate the rules of type aliases and why? I would be inclined to think that there are pitfalls that will cause insecure behavior.

, ++ aligned_storage:

template <std::size_t Len, std::size_t Alignment>
struct aligned_storage {
  typedef struct {
    alignas(Alignment) unsigned char __data[Len];
  } type;
};

boost , char "enable" aliasing.

std::aligned_union<>::type? , ?

+4
1

, , (char, signed char, unsigned char).

Boost , , function_buffer , , data. , data // To relax aliasing constraints, , Boost , , .

std::aligned_storage std::aligned_union , vtable , new (&buffer) F(std::move(f));, reinterpret_cast<F*>(&buffer) F*, F.

std::aligned_union - . , static_assert:

static_assert(sizeof(F) <= sizeof(buffer));
static_assert(alignof(F) <= alignof(buffer));
// OK to proceed
new (&buffer) F(std::move(f));
+2

All Articles