Доброе время суток. Пишу на С под windows xp. Среда разработки Visual Studio 2005. Имеется примерно следующая структура:
typedef struct {
short a;
short b;
short c;
double d;
double e;
double f;
} st;
Если посчитать размер структуры, получается 30 байт. Но! Функция sizeof(st) возвращает значение 32. Если из структуры убрать все даблы, то sizeof вернет вполне адекватные 6 байт. Не то, чтоб мне было жалко 2 байта, а все-таки в чем секрет?
Cantor wrote: > typedef struct { > short a; > short b; > short c; > double d; > double e; > double f; > } st;
А если так:
#pragma push()
#pragma pack(1)
typedef struct {
short a;
short b;
short c;
double d;
double e;
double f;
} st;
#pragma pop()
?
> Если посчитать размер структуры, получается 30 байт. Но! Функция > sizeof(st) возвращает значение 32. Если из структуры убрать все даблы, > то sizeof вернет вполне адекватные 6 байт. Не то, чтоб мне было жалко 2 > байта, а все-таки в чем секрет?
В выравнивании. Обращение к выравненым данным на х86 происходит намного
быстрее, чем к невыравненым. А на других архитектурах неправильное
выравнивание вообще вызывает аппаратную ошибку.
Здравствуйте, Cantor, Вы писали:
C>Доброе время суток. Пишу на С под windows xp. Среда разработки Visual Studio 2005. Имеется примерно следующая структура:
C>typedef struct { C> short a; C> short b; C> short c; C> double d; C> double e; C> double f; C>} st;
C>Если посчитать размер структуры, получается 30 байт. Но! Функция sizeof(st) возвращает значение 32. Если из структуры убрать все даблы, то sizeof вернет вполне адекватные 6 байт. Не то, чтоб мне было жалко 2 байта, а все-таки в чем секрет?
Этот вопрос — как анекдот про курочку, которая снесла дедушке яичко
В языках С/С++ никто никогда не обещал, что размер всей структуры равен суммарному размеру полей. Размер всей структуры моожет запросто быть больше, т.к. компилятор имеет право насовать внутрь (между полями и/или после них) дополнительных фиктивных байтов для целей выравнивания, например.
На платформах, которые допускают работу с невыровненными данными, как правило, существуют платформеннно-зависимые средства для управления выравниванием ('#pragma pack', например). Там обычно можно добиться желаемого тобою равенства. На платформах, где с выравниванием дела обстоят строже, таких средств может и не быть.
Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>В языках С/С++ никто никогда не обещал, что размер всей структуры равен суммарному размеру полей. Размер всей структуры моожет запросто быть больше, т.к. компилятор имеет право насовать внутрь (между полями и/или после них) дополнительных фиктивных байтов для целей выравнивания, например.
А для чистого Си такая гарантия существует/существовала?
Здравствуйте, Andir, Вы писали:
A>Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>>В языках С/С++ никто никогда не обещал, что размер всей структуры равен суммарному размеру полей. Размер всей структуры моожет запросто быть больше, т.к. компилятор имеет право насовать внутрь (между полями и/или после них) дополнительных фиктивных байтов для целей выравнивания, например.
A>А для чистого Си такая гарантия существует/существовала?
A>С Уважением, Andir!
Хмм. Дожился, что у меня аббревиатура C/C++ только собственно со вторым и ассоциируется Спасибо, хотя у меня было смутное ощущение, что в Си должно было быть такое ограничение, всё таки близко к ассемблеру.
Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>В языках С/С++ никто никогда не обещал, что размер всей структуры равен суммарному размеру полей. Размер всей структуры моожет запросто быть больше, т.к. компилятор имеет право насовать внутрь (между полями и/или после них) дополнительных фиктивных байтов для целей выравнивания, например.
АТ>На платформах, которые допускают работу с невыровненными данными, как правило, существуют платформеннно-зависимые средства для управления выравниванием ('#pragma pack', например). Там обычно можно добиться желаемого тобою равенства. На платформах, где с выравниванием дела обстоят строже, таких средств может и не быть.
On Wed, 08 Feb 2006 20:12:09 -0000, Cantor <51145@users.rsdn.ru> wrote:
> typedef struct { > short a; > short b; > short c; > double d; > double e; > double f; > } st; > > Если посчитать размер структуры, получается 30 байт. Но! Функция sizeof(st) возвращает значение 32. Если из структуры убрать все даблы, то sizeof вернет вполне адекватные 6 байт. Не то, чтоб мне было жалко 2 байта, а все-таки в чем секрет?
Размер стр-ры кратен максимальному align ее членов. align для встроенных типов обычно равен их размеру. Здесь максимальный align члена стр-ры есть alignof(double), что есть скорее всего 8, из-за чего размер стр-ры должен быть кратен 8.
Здравствуйте, Cantor, Вы писали:
C>Если посчитать размер структуры, получается 30 байт. Но! Функция sizeof(st) возвращает значение 32. Если из структуры убрать все даблы, то sizeof вернет вполне адекватные 6 байт. Не то, чтоб мне было жалко 2 байта, а все-таки в чем секрет?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: странное поведение sizeof
От:
Аноним
Дата:
09.02.06 22:31
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>На платформах, которые допускают работу с невыровненными данными, как правило, существуют платформеннно-зависимые средства для управления выравниванием ('#pragma pack', например). Там обычно можно добиться желаемого тобою равенства. На платформах, где с выравниванием дела обстоят строже, таких средств может и не быть.
Управление выравниванием — это всё-таки скорее свойство не платформы, а компилятора.
Потому что бывает, что компилятор делает структуру упакованной, но обращение к её поям вызывает ошибку (например, SIGBUS на SPARC).
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Андрей Тарасевич, Вы писали:
АТ>>На платформах, которые допускают работу с невыровненными данными, как правило, существуют платформеннно-зависимые средства для управления выравниванием ('#pragma pack', например). Там обычно можно добиться желаемого тобою равенства. На платформах, где с выравниванием дела обстоят строже, таких средств может и не быть.
А>Управление выравниванием — это всё-таки скорее свойство не платформы, а компилятора. А>Потому что бывает, что компилятор делает структуру упакованной, но обращение к её поям вызывает ошибку (например, SIGBUS на SPARC).
Именнно компилятор я и имею в виду под "платформой", т.е. то, что в спецификации языка называется "реализацией" ("implementation"). Формально в С/С++ абсолютно все зависит именно "от компилятора" и практичесики ничего от аппаратной платформы.