Путаница по поводу выравнивания данных - PullRequest
0 голосов
/ 22 сентября 2011

предположим, что структура определена следующим образом:

struct S{
    char a[3];
    char b[3];
    char c[3];
};

тогда что будет выводом printf ("% d", sizeof (S)) ?На моем компиляторе выражения Vc ++ 2008 вывод равен 9. И я запутался ... Я полагаю, что результат будет 12, но это не так.Разве компилятор не должен выровнять структуру по 4 или 8?

Ответы [ 6 ]

4 голосов
/ 22 сентября 2011

Значение выражения sizeof зависит от реализации; единственное, что гарантировано стандартом C ++, это то, что оно должно быть не менее девяти, поскольку вы храните девять char в struct.

Новый стандарт C ++ 11 имеет ключевое слово alignas, но это не может быть реализовано в VC ++ 08. Проверьте руководство вашего компилятора (см., Например, __declspec(align(#))).

2 голосов
/ 22 сентября 2011

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

1 голос
/ 22 сентября 2011

Существует ключ компилятора / Zp, который позволяет вам установить выравнивание членов структуры по умолчанию.Есть также некоторые другие методы для определения выравнивания на языке c.

Проверьте этот пост MSDN для деталей:

http://msdn.microsoft.com/en-us/library/xh3e3fd0(v=vs.80).aspx

Возможно, ваш компилятор использует один изэти настройки?

1 голос
/ 22 сентября 2011

Во-первых, выравнивание зависит от реализации, поэтому оно будет зависеть от компилятора.

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

Здесь char[3], таким образом, имеет выравнивание 1, и они идеально упакованы.

1 голос
/ 22 сентября 2011

Типичное требование, чтобы каждый элемент был выровнен, требует, чтобы сама структура была выровнена по наибольшему типу элемента.Поскольку все типы элементов char, выравнивание равно 1, поэтому заполнение не требуется.(Для массивов учитывается базовый тип (все удаленные экстенты).)

Подумайте о создании массива вашей структуры: вам понадобятся все члены всех элементовэтот массив для выравнивания.Но в вашем случае это всего лишь один большой массив символов, поэтому нет необходимости в заполнении.

Например, предположим, что на вашей платформе sizeof(short) == 2 и это выравнивание равно размеру, и рассмотрим struct X { char a; short b; char c; };.Затем существует одно байтовое внутреннее заполнение между a и b для правильного выравнивания b, но также одно байтовое заполнение терминала после c, так что вся структура имеет размер, кратный 2, наибольшему членуразмер.Таким образом, когда у вас есть массив X arr[10], все элементы arr будут правильно выровнены по отдельности.

0 голосов
/ 22 сентября 2011

Компилятору предоставляется достаточно широкая широта о том, как он выравнивает данные.Однако с практической точки зрения выравнивание датума не будет превышать его размера.То есть char s должны быть выровнены по байту, в то время как int s и long s часто выровнены по четыре байта.

Кроме того, struct s выровнены в соответствии со строгим требованиемих члены.

Итак, в вашем примере самым строгим требованием внутреннего выравнивания является выравнивание на 1 байт, поэтому структура выравнивается на 1 байт.Это означает, что он не требует заполнения.

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