Я не знаю хитрый способ сделать это, но вы могли бы сделать что-то ужасное, как это:
#include "packed.h"
struct Foo { /* members go here */ } PACKED;
#include "endpacked.h"
Затем для MSVC, упаковано. Ч .:
#define PACKED
#pragma pack(push,1)
endpacked.h
#pragma pack(pop)
#undef PACKED
Для GCC, упаковано. Ч .:
#define PACKED __attribute__ ((__packed__))
endpacked.h:
#undef PACKED
По сути, упаковка слишком зависит от платформы. Предположим, что ваша упакованная структура содержит 8-битные поля, и рассмотрим некоторую систему с 16-битным байтом. Он не может иметь структуру, представляющую ваши данные просто упаковкой - вам нужно знать, как 8-битные байты преобразуются в 16-битные байты при передаче между двумя системами. Структуре на 16-битной машине могут потребоваться битовые поля, и в этом случае вам нужно знать, как их выкладывает реализация.
Таким образом, если код предназначен для переносимости, вам может понадобиться определить любые упакованные структуры, которые вам нужны, в разделе для вашей платформы заголовочного файла. Или, скорее, структурируйте свой код так, чтобы будущий порт мог это делать, если это необходимо.