Как бы вы ни делали, юнит-тест из этого черт побери. Компиляторы и платформы сильно различаются по этим пунктам, поэтому никогда не думайте вслепую, что они согласованы.
Компиляторы могут изменять выравнивание структуры по своему усмотрению (например, по соображениям производительности). Запросы на некоторые ограничения обычно зависят от компилятора, хотя это поддерживается MSVC и gcc (через расширение)
#pragma pack(push, 1)
struct Foo {
// ..
};
#pragma pack(pop)
Это вынуждает его выравниваться по границам в 1 байт, так что нет логических значений.
Если вы хотите быть полностью совместимым, то сериализуйте каждое поле самостоятельно. Это действительно не так уж много работы.
Вам также придется иметь дело с порядком байтов, как уже упоминалось другими.