-2

Say I have

T rawData;
class A {
public:
  T data; // the only data member
  void process(void);
  // more methods;
};

What would be the safest way to A* ptr = (A*) &rawData; in order to use ptr->process(); and other methods?

The above approach works, but some compilers warn on strict aliasing rules being violated. Of course, it's safe to create an instance of A, set data and then retrieve it back after all the processing - but that's exactly what I want to avoid.

Outtruder
  • 227
  • 1
  • 4
  • The safest way to shoot yourself in the leg, huh? – Alexey S. Larionov Jun 30 '23 at 16:47
  • 2
    Related: [can I cast between an aggregate type with one member and that member's type?](https://stackoverflow.com/q/63456999/11082165) – Brian61354270 Jun 30 '23 at 16:47
  • Why do you want a pointer at all? Or are you asking about member function pointers?? – πάντα ῥεῖ Jun 30 '23 at 16:47
  • You don't need pointers for this make data private, and provide a getter. `class A{ public: T& data() noexcept { return data; } const T& data() const noexcept { return data; };` Anyway don't try to outsmart yourself to safe a bit on typing. – Pepijn Kramer Jun 30 '23 at 16:49
  • @Alexey S. Larionov Looking for some "approved" way :) – Outtruder Jun 30 '23 at 16:53
  • @Brian61354270 - close, but vice versa: T holds data for stuff similar to a big number implementation, most of the data are read from binary files. The class just implements methods to manipulate on those large data. – Outtruder Jun 30 '23 at 16:57
  • 1
    Make A a "borrowing" wrapper. `class A { T& obj; public: A(T& obj_) : obj{obj_} {} void process(); /*...*/ };` Then you can `T data; A a{data}; a.process();` your heart out. – Eljay Jun 30 '23 at 17:21
  • @Eljay Thank you! That's better than the answer I already accepted. I just wonder why my own earlier experiments on this did not work. – Outtruder Jun 30 '23 at 17:35

1 Answers1

2

some compilers warn on strict aliasing rules being violated

And they are absolutely correct. The solution, that they will accept:

A* ptr = new (&rawData) A;

However if you make void A::process() a free function void process(T& data), it will be a better solution.

273K
  • 29,503
  • 10
  • 41
  • 64
  • Thank you! Finally I see the use for "placement new". Creating a static process() method is possible but is not so elegant as there is a lot of other methods in the class, some work with references to other instances o the same class - re-writing al that in ol'plain C looks ugly. – Outtruder Jun 30 '23 at 17:10
  • You may place free functions in a namespace, say `namespace A`. – 273K Jun 30 '23 at 17:23