Лучший способ обратиться к размеру структуры (#pragma pack VS определенного размера) - PullRequest
1 голос
/ 08 января 2011

Предположим, у меня есть структура Foo

struct Foo{
    int a;
    short b;
    char  c;
};

И я должен записать эту структуру в н / б буфер. Мне нужно знать размер этой структуры. В моем окружении sizeof (Foo) возвращает 8, это нормально, я понимаю.

Это два способа указать точный размер, который я хочу записать в буфер

1. #define SIZEOF_FOO 7, и используйте это вместо sizeof(Foo)
2. Используя #pragma pack, я могу использовать sizeof(Foo), который вернет 7

Какой способ лучше, или есть ли другой способ сделать это?

Ответы [ 5 ]

2 голосов
/ 08 января 2011

Если вам нужно записать такую ​​структуру в сеть, пожалуйста, используйте структуру протокола или перенаправьте данные явно, используя протокол, который вы определяете независимо от структуры структуры.

В зависимости от подробностей двоичной структурыструктура, вероятно, вызовет боль в будущем.

Я слышал хорошие вещи о буферах протокола Google и Повышение сериализации , но я также не использовал их.

Я имел дело с протоколом, определенным в документе, и выводил данные в соответствии с этим протоколом, используя пользовательские процедуры маршалинга, или использовал описание IDL (что-то вроде аннотированной структуры C, которая использовалась для управлениягенератор кода, который создает подпрограммы сериализации / десериализации).

Таким образом, вы (или структура протокола) управляете использованием заполнения, независимо от того, что компилятор делает со структурой.Обратите внимание, что если вы используете инфраструктуру протокола, вам, как правило, нужно использовать ее на обоих концах (что может быть проблемой, если другой узел находится вне вашего контроля или встроенное устройство, которое, например, среда не поддерживает).

0 голосов
/ 08 января 2011

#define SIZEOF_FOO 7 без использования #pragma pack не следует использовать вообще.Причина в том, что когда вы вызываете send (или любую эквивалентную) функцию, передающую переменную вашего типа структуры и передаете размер данных как 7, функция send будет отправлять только первые 7 байты данных, и когдавы получите эти данные на другом конце, вы определенно запутаете много кода в своем коде.

Использование директив #pragma pack изменит выравнивание члена вашей структуры, и вы наверняка сэкономите несколько байтовпередача данных по сети, но если вы думаете с точки зрения оптимизации / производительности, эти несколько байтов незначительны.Хотя большинство приложений (которые я видел) использует #pragma pack для упаковки членов структуры, но это полностью зависит от ваших требований.

Одна из основных проблем с использованием #define SIZEOF_FOO 7 заключается в том, что при переносеВаш код для какой-либо другой платформы / архитектуры, фактический размер вашей структуры может не совпадать (7 байт), и тогда вам придется либо использовать зависящий от платформы макрос, либо придумать какую-то другую альтернативу.

короче говоря, вы всегда должны использовать sizeof вместо #define SIZEOF_FOO.

0 голосов
/ 08 января 2011

Этот вопрос сильно ошибочен. Размер Foo всегда тот, который sizeof(Foo) возвращает. Не предполагайте, не используйте желаемое за действительное, используйте sizeof.

На самом деле, я бы ожидал, что sizeof(Foo) будет 12, выравнивая все по 4-байтовой границе.

В любом случае, хорошая новость заключается в том, что sizeof разрешается во время компиляции и абсолютно не влияет на производительность. Так что нет никаких причин не использовать его.

#define SIZEOF_FOO (sizeof(Foo))
0 голосов
/ 08 января 2011

Я бы посоветовал написать структуру путем последовательного написания ее членов.Например, вы можете использовать ускоренную сериализацию.

Это позволит отделить представление структуры в памяти приложения от формата, используемого для передачи.

0 голосов
/ 08 января 2011

Директива #pragma pack изменяет текущее правило выравнивания для элементов структур, следующих за директивой. Следовательно, это влияет на размер структур, определенных после прагмы!

Скорее всего, вам это не нужно. Просто используйте sizeof(Foo) везде, где хотите узнать размер вашей структуры. И не пишите прагмы, так как они используются в некоторых особых случаях!

Вы можете увидеть эти ссылки, чтобы узнать подробнее о прагмах:

GCC - Структурно-упаковочные прагмы
MSVC ++ - Пакет
Pragma Pack

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...