· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.WIN32 —› Выравнивание данных

Посл.отвђт Сообщенiе


Дата: Ноя 17, 2004 02:04:56

опять 25, понимаю, но деца от етого никуда не могу ибо затупил конкретно...
в опчем, как и по каким правилам выравниваюца члены структур данных микрософтовскими компиляторами на платформе IA32? Только с примерами пжалуйста!

например, имеем следующее:

#pragma pack( 8 )
struct x {
char a;
DWORD b;
char c;
char d;
};
#pragma pack()

пусть:
x.a = 1;
x.b = 0x22222222;
x.c = 3;
x.d = 4;

получаем следующее:

sizeof(x) = 12

&(x.a) = 0x0012FD24
&(x.b) = 0x0012FD28
&(x.c) = 0x0012FD2C
&(x.d) = 0x0012FD2D

карта ф памяти:
0x0012FD24 - ...01 00 00 00 22 22 22 22 03 04 00 00 cc cc cc...

вопрос:

почему именно так? какая формула для вычисления оффсетов на члены структуры с участием коэффициента выравнивания (1,2,4,8 и 16)?

в РТФМах для меня написано непонятливо. Очень жду по-децки простых и наивных объяснений. Спасибо!


Дата: Ноя 17, 2004 05:02:11

RTFMSDN: #pragma pack( [ show ] | [ push | pop ] [, identifier ] , n )
„..The alignment of a member will be on a boundary that is either a multiple of n or a multiple of the size of the member, whichever is smaller.“
x.a: 0x0012FD24:  db  01 - выравнивается по границе байта;
x.b: 0x0012FD28:  dd  0x22222222 - выравнивается по границе dword, поэтому перед ним добавляется 3 байта;
x.c: 0x0012FD2C:  db  03 - выравнивается по границе байта;
x.d: 0x0012FD2D:  db  04 - выравнивается по границе байта;

Вот почему sizeof(x) = 12 - это уже сложнее, т.к. про это RTFMSDN действительно не пишет.
Вероятно, потому что структура находится в стэке ;-)
А стэк, как известно, всегда должен быть выровнен по границе не менее dword.


Дата: Ноя 17, 2004 11:18:53

sizeof(x) = 12, так как компилер по неизвестной мне причине не хочет выравнивать по 8, т.к.
как в структуре нет типа переменой, с размером 8. Компилер использует выравнивание по умолчанию(4байта).

К примеру:

#pragma pack(8)

struct x
{
char d;
double f;
};

size x = 16 байт.


Дата: Ноя 17, 2004 12:06:59

ozzman > „компилер по неизвестной мне причине не хочет выравнивать по 8“

„Выравнивание члена (структуры) будет (происходить) по границе, которая кратна либо n, либо размеру члена, в зависимости от того, что меньше

PS „Calling pack with no arguments sets n to its default value [...] The default value for n is 8. “
RTFMSDN рулит :-)


Дата: Ноя 17, 2004 17:34:16 · Поправил: ozzman

.


Дата: Ноя 17, 2004 17:46:12

насчет default packing value вообще сказка ;)
для Вижуал 6.0 и до него - дефолтное значение 4 байта, для Вижуал 7.0 это 8 байт...
так шта не всегда ртфм рулит ;) я счаз занят, вечером поковыряюсь... просто дело в том, что перечисленные S_T_A_S_ ом правила (из нового МСДНа) не всегда работают, и все что касается выравнивания мемберов из МСДНа я внимательно читал и перечитывал не один раз... но что-то тут не так, дома посмотрю пример который посылает в далекие края все эти правила...


Дата: Ноя 17, 2004 21:45:26

NeuronViking
у меня временно стоит старый мсдн, и там написано про дефолтное выравнивание для старых версий VS. Думаю в новом мсдн можно найти для новых версий, соотв-но.


Дата: Ноя 18, 2004 04:05:49 · Поправил: S_T_A_S_

Я смотрю апрель 2003: ms-help://MS.MSDNQTR.2003APR.1033/vclang/html/_predir_pack.htm
или вот
и так как минимум с 2000 года

Когда речь идёт о стэке, нужно учитывать особенности архитектуры, например если ESP не кратен 4 под NT, то система просто грохнет прогу при первой возможности.


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.057