В чем разница между «#pragma pack» и «__attribute __ ((aligned))»

Например:

#pragma pack ( L1_CACHE_LINE ) struct A { // ... }; #pragma pack ()

  



A a ; gc prettyprint prettyprinted ">struct A {
  //...
};

A a __attritube__((aligned(L1_CACHE_LINE)))

а также

__attribute__((aligned(byte-alignment)))

В чем разница между thwm?

Спасибо заранее!

gcc,attributes,

16

Ответов: 2


10 принят

#define L1_CACHE_LINE 2 структура { u_int32_t в __attribute__ ( ( выровнен ( L1_CACHE_LINE )) ); u_int32_t b __attribute__ ( ( выровнено ( L1_CACHE_LINE )) ); u_int16_t c __attribute__ ( ( выровнено ( L1_CACHE_LINE )) ); u_int16_t d __attribute__ ( ( выровнено ( L1_CACHE_LINE )) ); u_int32_t e __attribute__ ( ( выровнено ( L1_CACHE_LINE )) ); }; #pragma pack ( L1_CACHE_LINE ) struct A { u_int32_t a ; u_int32_t b ; u_int16_t c ; u_int16_t d ; u_int32_t e ; }; #pragma pack () (байт-выравнивание) воздействует на каждый член a __attritube __ ((aligned (L1_CACHE_LINE))), заданный входным сигналом байта или на их границе естественного выравнивания, в зависимости от того, что меньше.

u_int32_t aВлияют на выравнивание структуры Aimum переменного (или структуру поле , если указано в пределах структуры)

Я считаю, что следующие эквиваленты

#pragma pack

где A __attribute__((aligned))застрахован #pragma packвнутри, struct Aбудет заполнен 2 байтами, но не будет выравнивать другую переменную таким же образом.

Справка:

  1. http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=%2Fcom.ibm.vacpp6m.doc%2Fcompiler%2Fref%2Frnpgpack.htm
  2. http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/attributes-variables.html

alignedявляется синтаксисом Microsoft, который был перенесен в GCC по соображениям совместимости.

#pragma pack является синтаксисом, специфичным для GCC (не поддерживается MSVC).

Вот краткое описание различий:

  • #pragma pack(и варианты) является более кратким и представляет оба атрибута __attribute__и #pragma packв синтаксисе GCC (см. пример ниже);
  • #pragma pack(n)применяется к каждому определению структуры, помещенному после того, где он вставлен (или пока другой не __attribute__((packed,aligned(n)))переопределяет его), тогда как GCC ns определяются локально для типа;
  • #pragma packменее мелкозернистый, чем атрибуты: он не может применяться только к нескольким членам структуры. На практике, однако, это редко бывает проблемой, поскольку вам редко нужны разные настройки выравнивания и упаковки для членов одной и той же структуры.

В очень сжатом виде #pragma packэто примерно эквивалентно : он определяет как упаковку (уплотняющие структуры для сохранения памяти), так и минимальное выравнивание . Следовательно, (минимальное выравнивание) на прагме.#include <stdio.h> #include <stddef.h> // for offsetof() #pragma pack(push, 4) struct st { char c; double d; short e; }; #pragma pack(pop) // disables the effect of #pragma pack from now on struct st2 { char c __attribute__((packed,aligned(4))); double d __attribute__((packed,aligned(4))); short e __attribute__((packed,aligned(4))); }; void main() { printf("offsetof(struct st, d) = %zu ", offsetof(struct st, d)); printf("offsetof(struct st2, d) = %zu ", offsetof(struct st2, d)); printf("offsetof(struct st, e) = %zu ", offsetof(struct st, e)); printf("offsetof(struct st2, e) = %zu ", offsetof(struct st2, e)); }n

В принципе, a€?packeda€™ attribute ignored for field of type a€?chara€™можно эмулировать с использованием атрибутов GCC, но не наоборот, из-за более тонкого контроля, определяемого атрибутами.

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

aligned

GCC выдает предупреждение на этом примере: aligned. Действительно, более кратким и правильным решением является применение minко всей структуре (как это сделал @Hagai), что эквивалентно 1 . Обратите внимание, однако, что вы не можете просто применить maxко всей структуре: поведение не эквивалентно применению #pragma packк каждому полю отдельно.

Обратите внимание, что если вы комбинируете оба (прагма + атрибуты) в одном и том же определении структуры, алгоритм является более сложным, поскольку он должен учитывать несколько ограничений, что приводит к некоторым min/ alignedвычислениям между (1) выравниванием, заданным выражением #pragma pack(2) минимальное выравнивание типа члена и (3) alignedатрибуты, объявленные в поле (если есть).

1 Из документации GCC :

Указание упакованного атрибута для типов struct и union эквивалентно заданию упакованного атрибута для каждого из элементов структуры или объединения.

НКУ, атрибуты,