опять 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)? в РТФМах для меня написано непонятливо. Очень жду по-децки простых и наивных объяснений. Спасибо!
RTFMSDN: #pragma pack( [ show ] | [ push | pop ] [, identifier ] , n ) Код (Text): 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.
sizeof(x) = 12, так как компилер по неизвестной мне причине не хочет выравнивать по 8, т.к. как в структуре нет типа переменой, с размером 8. Компилер использует выравнивание по умолчанию(4байта). К примеру: #pragma pack(8) struct x { char d; double f; }; size x = 16 байт.
ozzman > „Выравнивание члена (структуры) будет (происходить) по границе, которая кратна либо n, либо размеру члена, в зависимости от того, что меньше“ PS RTFMSDN рулит
насчет default packing value вообще сказка для Вижуал 6.0 и до него - дефолтное значение 4 байта, для Вижуал 7.0 это 8 байт... так шта не всегда ртфм рулит я счаз занят, вечером поковыряюсь... просто дело в том, что перечисленные S_T_A_S_ ом правила (из нового МСДНа) не всегда работают, и все что касается выравнивания мемберов из МСДНа я внимательно читал и перечитывал не один раз... но что-то тут не так, дома посмотрю пример который посылает в далекие края все эти правила...
NeuronViking у меня временно стоит старый мсдн, и там написано про дефолтное выравнивание для старых версий VS. Думаю в новом мсдн можно найти для новых версий, соотв-но.
Я смотрю апрель 2003: ms-help://MS.MSDNQTR.2003APR.1033/vclang/html/_predir_pack.htm или вот и так как минимум с 2000 года Когда речь идёт о стэке, нужно учитывать особенности архитектуры, например если ESP не кратен 4 под NT, то система просто грохнет прогу при первой возможности.
со стеком вроде бы все понятно. если я не ошибаюсь то на IA-32 стековые данные всегда выровнены на естественную границу (2 или 4 байта)
Дело не в этом. В ядре NT есть проверки, если ESP user-процесса не кратен 4, то система его завершает.
верно =) потому чьто ядро работает на ИА-32 в протектед модеи соответственно естественная граница выравнивания как следуюет из спецификации Intel IA-32 есьм 4 байта
А user в каком режиме работает? %) Зацитируем IA-32 Intel® Architecture Software Developer’s Manual Volume 1: Basic Architecture Мастдае, например, не следит за стэком. NT, кстати, проверяетне только кратность ESP потока 4м, но и не выход за пределы, храняшиеся в TIB [fs:4];//StackBase - верхняя граница [fs:8];//StackLimit - нижняя граница