Разница между атрибутом attribute((packed)) и прагмой #pragma pack заключается в их назначении и области применения. 12
Атрибут attribute((packed)) предназначен для упакованных структур и поддерживается только в компиляторе GCC. 1 Он упаковывает поля в структуру без дыр, обусловленных выравниванием. 1 Атрибут затрагивает битовые поля, то есть упаковывает их вплотную, без учёта стандартной подложки. 1
Прагма #pragma pack изначально является расширением для компилятора Visual C++, но была реализована и в GCC для совместимости с VC++. 2 При помощи этой конструкции код получается более переносимым. 1 Прагма влияет на выравнивание элементов структуры, что может сказаться на выравнивании всей структуры. 4
Ещё одно отличие заключается в том, что прагма #pragma pack вступает в силу с точки определения и до следующего #pragma pack, в то время как атрибут attribute((packed)) эффективен только для определения, к которому он присоединён. 2