// file x.h
struct X {
  int data;
};


// file y.h
#include <cstddef>

class Y {
public:
  Y();
  ~Y();
  /*...*/
private:
  static const size_t sizeofx = 8;
  char _x[sizeofx];
};


// file y.cpp
#include <new>
//#include "y.h"
//#include "x.h"

Y::Y() {
  // compile-time check
  static_assert(sizeofx >= sizeof(X), "sizeofx too small");
  // does not allocate memory, but constructs an object at &_x[0]
  new (&_x[0]) X;
}

Y::~Y() {
  (reinterpret_cast<X*>(&_x[0]))->~X();
}


// file main.cpp
//#include "y.h"

int main()
{
  Y y;
  return 0;
}