1

Is this C++ code valid or undefined behaviour? The idea is to be able to wrap a POD you have no control over into another struct to provide helper functions but still be able to use it as if it was the original POD.

struct Data
{
  ...//POD
};
struct Wrapper
{
  Data data;//contains only this
  void HelperFuncA();
  void HelperFuncB();
  ...//only member functions
};

...
//is this legal?
std::vector<Wrapper> vec_of_wrappers;
Data* array_of_data = reinterpret_cast<Data*>(vec_of_wrappers.data());
Ocelot
  • 113
  • 1
  • 6
  • No, this is not valid. Never treat arrays polymorphically. – SergeyA Nov 09 '21 at 19:28
  • That's definitely illegal. How can you be sure that the compiler won't add some padding to objects of type `Wrapper` (or, indeed, that `Data` comes at the beginning)? – Paul Sanders Nov 09 '21 at 19:34
  • If it were `vec_of_wrappers(1)`, then it could be valid on some system, otherwise `data()` is just `nullptr` – Barmak Shemirani Nov 09 '21 at 19:41
  • @PaulSanders there is never padding before the first element, it is guaranteed by standard. The code is illegal for other reasons (see my answer) – SergeyA Nov 09 '21 at 19:47
  • `Data* array_of_data = reinterpret_cast(vec_of_wrappers.data());` is the start of Undefined Behaviour (you would need to dereference `array_of_data` for actuals UB) as none of the allowed conversions for [reinterpret_cast](https://en.cppreference.com/w/cpp/language/reinterpret_cast) are present in the above code. See the __Type aliasing__ section in the above link. – Richard Critten Nov 09 '21 at 20:20
  • You don't need member functions to operate on a POD. What's wrong with `void HelperFuncA(Data* d)`? – n. m. could be an AI Nov 09 '21 at 20:55

1 Answers1

-1

Now, this code is not valid. There are several reasons for this. First, casting a pointer to the first member of the struct to the struct itself violates strict aliasing rule. This you can fix by making Wrapper a child class of the Data.

The second issue is more problematic, as you are trying to treat an array (vector in this case) polymorphically. sizeof Data is different from the sizeof Wrapper, so an attempt to index an array of Wrapper elements as if it was an array of Data elements will end up pointing into random areas of the array.

SergeyA
  • 61,605
  • 5
  • 78
  • 137