Jaka jest różnica między "# pragma pack " a " attribute ((aligned))"
#pragma pack(L1_CACHE_LINE)
struct A {
//...
};
#pragma pack()
A a;
I
struct A {
//...
};
A a __attritube__((aligned(L1_CACHE_LINE)))
Jaka jest różnica między nimi? 2 answers
Pakiet # pragma (Byte-alignment) powoduje, że każdy element struktury jest określony przez wejście Byte-alignment lub na ich naturalnej granicy wyrównania, w zależności od tego, która z tych wartości jest mniejsza.
__attribute__((aligned(byte-alignment)))
wpływa na minimalne wyrównanie zmiennej (lub pola struct, jeśli jest określone w strukturze)
Uważam, że poniższe są równoważne
#define L1_CACHE_LINE 2
struct A
{
u_int32_t a __attribute__ ( (aligned(L1_CACHE_LINE)) );
u_int32_t b __attribute__ ( (aligned(L1_CACHE_LINE)) );
u_int16_t c __attribute__ ( (aligned(L1_CACHE_LINE)) );
u_int16_t d __attribute__ ( (aligned(L1_CACHE_LINE)) );
u_int32_t e __attribute__ ( (aligned(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()
Gdzie a __attritube__((aligned(L1_CACHE_LINE)))
będzie ubezpieczać u_int32_t a
wewnątrz struct A
będzie wyrównany z 2 bajtem, ale nie będzie wyrównywał drugiej zmiennej w tym samym sposób.
Odniesienie:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-06 06:32:45
#pragma pack
jest składnią Microsoft, która została przeniesiona do GCC ze względu na kompatybilność.
__attribute__((aligned))
jest składnią specyficzną dla GCC (nieobsługiwaną przez MSVC).
Oto podsumowanie różnic:
-
#pragma pack
(i warianty) jest bardziej zwięzły i reprezentuje zarówno atrybutypacked
ialigned
w składni GCC (patrz przykład poniżej); -
#pragma pack
stosuje się do każdej definicji struktury umieszczonej po miejscu, w którym została wstawiona (lub do czasu nadpisania innej#pragma pack
to), podczas gdy GCC__attribute__
S są definiowane lokalnie do typu; -
#pragma pack
jest mniej drobnoziarnista niż atrybuty: nie może być stosowana tylko do kilku elementów struktury. W praktyce jednak rzadko jest to problemem, ponieważ rzadko będziesz potrzebował różnych ustawień wyrównywania i pakowania dla członków tej samej struktury.
W bardzo zwięzły sposób, {[10] } jest mniej więcej równoważne __attribute__((packed,aligned(n)))
: definiuje zarówno pakowanie (zagęszczanie struktur dla celów oszczędzania pamięci), jak i minimalne wyrównanie . Stąd n
(Minimalne wyrównanie) na pragmie.
W zasadzie, #pragma pack
można emulować używając atrybutów GCC, ale nie odwrotnie, ze względu na lepszą kontrolę nad atrybutami.
Oto przykład, który możesz przetestować na GCC: pierwsza definicja używa #pragma pack
, a druga używa atrybutów. Układ jest taki sam w obu przypadkach.
#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\n", offsetof(struct st, d));
printf("offsetof(struct st2, d) = %zu\n", offsetof(struct st2, d));
printf("offsetof(struct st, e) = %zu\n", offsetof(struct st, e));
printf("offsetof(struct st2, e) = %zu\n", offsetof(struct st2, e));
}
GCC emituje ostrzeżenie na tym przykładzie: ‘packed’ attribute ignored for field of type ‘char’
. Rzeczywiście, bardziej zwięzłym i właściwym rozwiązaniem jest apply packed
to the whole struct (as @Hagai did), which is equivalent1. Należy jednak pamiętać, że nie można po prostu zastosować aligned
do całej struktury: zachowanie jest , a nie równoważne zastosowaniu aligned
do każdego pola osobno.
Zauważ, że jeśli połączysz oba (pragma + atrybuty) w tej samej definicji struktury, algorytm jest bardziej złożony, ponieważ musi przestrzegać kilku ograniczeń, które skutkują pewnymi min
/max
obliczenia między (1) wyrównanie podane przez #pragma pack
, (2) Minimalne wyrównanie typu member oraz (3) aligned
atrybuty zadeklarowane w polu (jeśli występują).
1 Z dokumentacji GCC :
Określenie atrybutu packed dla typów struct i union jest równoważne określeniu atrybutu packed dla każdej struktury lub członków Unii.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-31 08:15:08