2016-01-04 2 views
1

Мы знаем, что _attribute__((__packed__)) означает (скорее всего) «не вставлять никаких отступов, чтобы ускорить работу», а также может означать «не вставлять выравнивания для сохранения выравнивания».Структура упаковки с использованием __attribute __ ((__ставляется__)) в GNU GCC

struct structure2 
{ 
    int id1 __attribute__((__packed__)); 
    char name __attribute__((__packed__)); 
    int id2 __attribute__((__packed__)); 
    char c __attribute__((__packed__)); 
    float percentage __attribute__((__packed__)); 
}; 
struct structure2 b; 
printf(" \n\nsize of structure2 in bytes : %d\n", sizeof(b));// output = 20 

Почему все отступы не удаляются (выход = 14)?

+0

Прежде чем использовать расширение поставщика, обязательно прочитайте документацию (https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-g_t_0040code_007bpacked_007d-type-attribute-3509). В нем ясно сказано, что атрибут может быть привязан только к типам struct, union и enum. –

+0

Вы хотите, чтобы 'struct' была упакована, а не отдельные поля (которые уже упакованы, поскольку они являются скалярными типами). – Olaf

+0

Я видел этот тип структуры из http://grok2.tripod.com/structure_packing.html –

ответ

6

Try:

struct __attribute__((__packed__)) structure2 
{ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    int id1; 
    char name; 
    int id2; 
    char c; 
    float percentage; 
}; 

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

+0

@dragosht, 'struct __attribute __ ((__ставляется__)) structure2', это нормально, но вывод по-прежнему 20 –

+1

@AnimeshKumarPaul: невозможно воспроизвести, [работает для меня] (http://melpon.org/wandbox/permlink/7BDgXccSWkQQLwdJ). –

+0

@AnimeshKumarPaul С какой версией gcc вы компилируете? – dragosht

2

выглядит как ошибка для меня ...

С помощью компилятора ((tdm64-1) 4.7.1) и соответствующий packed атрибут Я получаю такое же поведение - см main разборку ниже:

0000000000401500 <main>: 
    401500:  55      push %rbp 
    401501:  48 89 e5    mov %rsp,%rbp 
    401504:  48 83 ec 40    sub $0x40,%rsp 
    401508:  e8 a3 11 00 00   callq 4026b0 <__main> 
    40150d:  ba 14 00 00 00   mov $0x14,%edx <-- your sizeof here 
    401512:  48 8d 0d 07 7b 00 00 lea 0x7b07(%rip),%rcx  # 409020 <.rdata> 
    401519:  e8 b2 60 00 00   callq 4075d0 <printf> 
    40151e:  b8 00 00 00 00   mov $0x0,%eax 
    401523:  48 83 c4 40    add $0x40,%rsp 
    401527:  5d      pop %rbp 
    401528:  c3      retq 
    ... 

Использование gcc (GCC) 4.9.3 в Cygwin я получаю:

00000001004010e0 <main>: 
    1004010e0: 55      push %rbp 
    1004010e1: 48 89 e5    mov %rsp,%rbp 
    1004010e4: 48 83 ec 30    sub $0x30,%rsp 
    1004010e8: e8 33 00 00 00   callq 100401120 <__main> 
    1004010ed: ba 0e 00 00 00   mov $0xe,%edx <-- your sizeof here 
    1004010f2: 48 8d 0d 37 1f 00 00 lea 0x1f37(%rip),%rcx  # 100403030 <.rdata> 
    1004010f9: e8 32 00 00 00   callq 100401130 <printf> 
    1004010fe: b8 00 00 00 00   mov $0x0,%eax 
    100401103: 48 83 c4 30    add $0x30,%rsp 
    100401107: 5d      pop %rbp 
    100401108: c3      retq 
    ... 

Итак, по какой-то причине компилятор вы используете, кажется, ИГ nore атрибут. Возможно, вы захотите попробовать более новую версию, но самая новая версия этого TDM-GCC кажется 5.1.0.

+0

Содержит ли компилятор багги также поддержку синтаксиса для каждого поля? Недавний GCC не делает (это не позволяет атрибут, скажем, поле 'char'). –

+0

@ KerrekSB Не знаю. Я тестировал только ваш пример кода ... – dragosht

+1

Да. Я просто видел, что OP копировал код из внешнего документа, поэтому мне было интересно, поддерживал ли он когда-то GCC. Ничего. –