2015-09-20 4 views
0

Я прошел через this question, чтобы подтвердить свое понимание структуры padding.I теперь сомневаюсь. Когда я делаю что-то вроде этого:Создайте байты заполнения для структуры, вложив его в объединение

#include <stdio.h> 

#define ALIGNTHIS 16 //16,Not necessarily 

union myunion 
{ 
    struct mystruct 
    { 
    char a; 
    int b; 
    } myst; 
    char DS4Alignment[ALIGNTHIS]; 
}; 

//Main Routine 
int main(void) 
{ 
    union myunion WannaPad; 

    printf("Union's size: %d\n\ 
     Struct's size: %d\n", sizeof(WannaPad), 
     sizeof(WannaPad.myst)); 

    return 0; 
} 

Выход:

Union's size: 16 
Struct's size: 8 

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

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

Есть ли работа для работы, так как мне бы хотелось?

+0

Какой компилятор и какие опции используются? – Matt

+3

Объединение будет достаточно большим, чтобы удерживать любой из внутренних типов, но внутренние типы не будут дополняться, чтобы соответствовать другим внутренним типам. – CoffeeandCode

+1

«* [...] размер [структуры] должен быть [padded] *« Почему? Для чего смысл/использование? Какой будет выигрыш? – alk

ответ

1

Должен ли я ожидать, что структура будет дополнена 8 байтами?

Нет, поскольку struct mystruct рассматривается/обрабатывается самостоятельно. char был дополнен sizeof (int) -1 байт, чтобы правильно выровнять int. Это не меняется, даже если кто-то где-то иногда решает использовать этот самый struct mystruct внутри другого типа.

+0

'sizeof (int)' не привязан к 4. – Matt

+0

@ user4419802: Правильно и спасибо! Исправлено ... - :-) – alk

+1

«Это не изменится, даже если кто-то где-то иногда решает использовать эту самую структуру в другом типе». Ага! Это именно то, чего я пропустил. – Adithya

1

По умолчанию struct проложен, поэтому int b поле выравнивается по границе sizeof(int). Есть несколько способов обойти это:

  • явно использовать наполнители, где это необходимо: char a; char _a[sizeof(int)-1]; int b;
  • использование зависит от компилятора Прагма для упаковки struct на границе байта
  • использование ключа командной строки и т.д.
2

Подумайте об этом логично.

Представьте меня был союз с некоторыми основными типами в нем:

union my_union{ 
    int i; 
    long l; 
    double d; 
    float f; 
}; 

вы бы ожидать sizeof(int) == sizeof(double)?

Внутренние типы всегда будут их размера, но объединение всегда будет достаточно большим, чтобы удерживать любые его внутренние типы.

+0

Я бы не ожидал этого для примитивных типов данных, таких как те, которые вы упомянули. Но когда вы рассматриваете пользовательскую структуру типа данных, такую ​​как структура, может быть применена другая логика, что, похоже, не так.Если бы я объявил структуру снаружи и определил ее экземпляр внутри союза, я бы не смутился в первую очередь! Спасибо, в любом случае :-) – Adithya

+0

@Adithya Не имеет значения, примитив или структура внутри союза. Это было просто для иллюстрации вашей ошибки в мышлении. * any * type будет рассматриваться как вне «union». Никакой «другой логики» не может быть применен. – CoffeeandCode

Смежные вопросы