Как использовать pack в vs и gcc

До сегодняшнего дня я использовал следующую технику для упаковки структур:

#pragma pack(push,1)
struct mystruct
{
char a1;
char a2;
int a3;
}
#pragma pack(pop)

mystruct mydata()
{
mystruct ms;
ms.a1='a';
ms.a2='b';
ms.a3=12;
return ms;
}

и предположил, что ms упакован как 1, но сегодня кто-то сказал мне, что в вышеприведенном определении ms упакован как 4, так как pack не влияет на определение, но на объявление. http://msdn.microsoft.com/en-us/library/aa273913%28v=vs.60%29.aspx

Может кто-нибудь уточнить, было ли то, что я сделал, правильно или нет?

2

Решение

Стандарт определяет § 3.1 / 2

Декларация является определением если она не объявляет функцию без указания тела функции (8.4), она
содержит спецификатор extern (7.1.1) или спецификацию связи25 (7.5), а также инициализатор и тело функции,
он объявляет член статических данных в определении класса (9.2, 9.4), это объявление имени класса (9.1), это
непрозрачное-enum-объявление (7.2), это шаблон-параметр (14.1), это объявление параметра (8.3.5) в
декларатор функции, который не является декларатором определения функции, или это объявление typedef (7.1.3),
декларация псевдонимов (7.1.3), декларация использования (7.3.3), декларация static_assert (раздел 7), объявление атрибута
(Пункт 7), пустое объявление (пункт 7) или директива об использовании (7.3.4).

таким образом, у вас есть определение структуры, как вы правильно заметили, но это также объявление, поэтому случай

пакет не влияет на определения

применяется, но не для декларации. На самом деле MSVC и GCC / Clang правильно упаковать выше с 1

struct mystruct_not_packed
{
char a1;
char a2;
int a3;
};

#pragma pack(push,1)
struct mystruct
{
char a1;
char a2;
int a3;
};

mystruct_not_packed object; // This doesn't apply
#pragma pack(pop)

int main(int argc, char *argv[])
{
std::cout << sizeof(mystruct) << std::endl; // 6
std::cout << sizeof(mystruct_not_packed) << std::endl; // 8
std::cout << sizeof(object) << std::endl; // 8
}

(протестировано с MSVC2013U4)

Пример с gcc

1

Другие решения

Фраза «Прагма не влияет на определения» означает, что если вы напишите

struct mystruct
{
char a1;
char a2;
int a3;
};

#pragma pack(push,1)
mystruct ms;
#pragma pack(pop)

Это не повлияет на упаковку ms,

Но в вашем примере ms будет упаковано в 1, вот и весь смысл pragma pack,

демонстрация

(Результаты MSVC 2013 8 6 на этот код, а также лязг и gcc на колиру)

0

По вопросам рекламы [email protected]