fork download
  1. #include <iostream>
  2. #include <stdint.h>
  3. #include <stddef.h>
  4. #include <assert.h>
  5.  
  6. #ifndef UINT64_C
  7. #define UINT64_C(n) n##ULL
  8. #endif
  9.  
  10. static const uint64_t stchkValue = UINT64_C(0xbbbbfeedfacebbbb);
  11. static const uint64_t enchkValue = UINT64_C(0xeeeefeedfaceeeee);
  12.  
  13. template<typename T>
  14. struct Item
  15. {
  16. uint64_t stchk;
  17. union {
  18. char mem[sizeof(T)];
  19. //__m128i align; ideone compiler options disallow
  20. } data;
  21. uint64_t enchk;
  22.  
  23. Item()
  24. : stchk(stchkValue)
  25. , enchk(enchkValue)
  26. {
  27. }
  28.  
  29. void construct()
  30. {
  31. new (&data) T();
  32. }
  33. };
  34.  
  35. template<typename T>
  36. static void destruct(T *p)
  37. {
  38. // Try to reverse calculate the Item pointer from the mem pointer
  39. // tried auto ofs = offsetof(Item<T>, data);
  40. // tried auto ofs = offsetof(Item, data);
  41. typedef Item<T> NiceItem;
  42. auto ofs = offsetof(NiceItem, data);
  43. //auto ofs = (size_t)(uintptr_t)(&((T*)0)->data);
  44.  
  45. std::cout << "offset is " << ofs << std::endl;
  46.  
  47. auto self = reinterpret_cast<Item<T>*>((uintptr_t)p - ofs);
  48. assert(self->stchk == stchkValue);
  49. assert(self->enchk == enchkValue);
  50. assert(reinterpret_cast<T*>(self->data.mem) == p);
  51.  
  52. p->~T();
  53. }
  54.  
  55. int main()
  56. {
  57. Item<int> x;
  58. x.construct();
  59. auto p = &x.data;
  60. destruct(p);
  61. }
  62.  
Success #stdin #stdout 0s 2884KB
stdin
Standard input is empty
stdout
offset is 8