I have a rather odd problem: I need to maintain a chunk of code which involves structs. These structs need to be modified by adding fields to them from time to time. Adding to the end of a struct is what you are supposed to do, and any time you add a field to the middle of a struct, you’ve broken the code in a non-trivial way.
It’s become a nightmare to maintain since these do need to be modified occasionally, and the only way to get out of the business of modifying these structs (and having them break due to the layout change of the previous fields) is to completely rewrite a huge swath of code, which is simply not possible.
What I need to do is find a way to make changing the layout of the struct a compile error. Now, I can solve the problem this way:
struct Foo
{
int *Bar;
int Baz;
};
#ifdef _x86_
static_assert(_offsetof(Foo, Bar) == 0);
static_assert(_offsetof(Foo, Baz) == 4);
#else
static_assert(_offsetof(Foo, Bar) == 0);
static_assert(_offsetof(Foo, Baz) == 8);
#endif
However, this is a huge amount of work because there are roughly 20 of these structs with 4-10 fields each. I can probably minimize this by only asserting that the last field’s offset is at the correct location, but this is still a lot of manual work.
Does anyone have any suggestions for a compiler trick, C++ template metaprogram trick, or otherwise, that would make this easier?
you should probably use a form of struct inheritence (c -style) to make this a little easier for everyone to figure out
basically you would have the struct you dont want modified
and a FooExtensions (or whatever) struct that people can modify willy-nilly
then to pass a FooExtnesions object to a method expecting a Foo just cast it to Foo, the member alignments will work out. this is a more common pattern for maintaining this kind of backwards compatibility. Obviously people can still ignore the convention but this makes it a little easier to succeed.
you can still add all the static_asserts to make sure that Foo isn’t modified