странное поведение sizeof
От: Cantor  
Дата: 08.02.06 20:12
Оценка:
Доброе время суток. Пишу на С под 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 байта, а все-таки в чем секрет?
Re: странное поведение sizeof
От: Cyberax Марс  
Дата: 08.02.06 20:17
Оценка:
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 происходит намного
быстрее, чем к невыравненым. А на других архитектурах неправильное
выравнивание вообще вызывает аппаратную ошибку.
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re: странное поведение sizeof
От: Андрей Тарасевич Беларусь  
Дата: 09.02.06 01:09
Оценка:
Здравствуйте, 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', например). Там обычно можно добиться желаемого тобою равенства. На платформах, где с выравниванием дела обстоят строже, таких средств может и не быть.
Best regards,
Андрей Тарасевич
Re[2]: странное поведение sizeof
От: Andir Россия
Дата: 09.02.06 02:34
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>В языках С/С++ никто никогда не обещал, что размер всей структуры равен суммарному размеру полей. Размер всей структуры моожет запросто быть больше, т.к. компилятор имеет право насовать внутрь (между полями и/или после них) дополнительных фиктивных байтов для целей выравнивания, например.


А для чистого Си такая гарантия существует/существовала?

С Уважением, Andir!
Re[3]: странное поведение sizeof
От: unix_hater  
Дата: 09.02.06 07:55
Оценка:
Здравствуйте, Andir, Вы писали:

A>Здравствуйте, Андрей Тарасевич, Вы писали:


АТ>>В языках С/С++ никто никогда не обещал, что размер всей структуры равен суммарному размеру полей. Размер всей структуры моожет запросто быть больше, т.к. компилятор имеет право насовать внутрь (между полями и/или после них) дополнительных фиктивных байтов для целей выравнивания, например.


A>А для чистого Си такая гарантия существует/существовала?


A>С Уважением, Andir!
Re[4]: странное поведение sizeof
От: Andir Россия
Дата: 09.02.06 08:14
Оценка:
Здравствуйте, unix_hater, Вы писали:

Хмм. Дожился, что у меня аббревиатура C/C++ только собственно со вторым и ассоциируется Спасибо, хотя у меня было смутное ощущение, что в Си должно было быть такое ограничение, всё таки близко к ассемблеру.

С Уважением, Andir!
Re[2]: странное поведение sizeof
От: sadomovalex Россия http://sadomovalex.blogspot.com
Дата: 09.02.06 08:36
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>В языках С/С++ никто никогда не обещал, что размер всей структуры равен суммарному размеру полей. Размер всей структуры моожет запросто быть больше, т.к. компилятор имеет право насовать внутрь (между полями и/или после них) дополнительных фиктивных байтов для целей выравнивания, например.


АТ>На платформах, которые допускают работу с невыровненными данными, как правило, существуют платформеннно-зависимые средства для управления выравниванием ('#pragma pack', например). Там обычно можно добиться желаемого тобою равенства. На платформах, где с выравниванием дела обстоят строже, таких средств может и не быть.


по этой теме советую статью Саттера C++, the real world, and link and binary compatibility в CUJ
"Что не завершено, не сделано вовсе" Гаусс
Re: странное поведение sizeof
От: MaximE Великобритания  
Дата: 09.02.06 10:16
Оценка: 1 (1)
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.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 2.0
Re: странное поведение sizeof
От: Cantor  
Дата: 09.02.06 14:09
Оценка:
Всем огромное спасибо за советы! Очень помогли
Re: Что вернёт sizeof?
От: Erop Россия  
Дата: 09.02.06 14:15
Оценка:
Здравствуйте, Cantor, Вы писали:

C>Если посчитать размер структуры, получается 30 байт. Но! Функция sizeof(st) возвращает значение 32. Если из структуры убрать все даблы, то sizeof вернет вполне адекватные 6 байт. Не то, чтоб мне было жалко 2 байта, а все-таки в чем секрет?


Я как-то уже писал про то, "Что вернёт sizeof
Автор: Erop
Дата: 28.10.05
"

Вот, читай, надеюсь, что будет интересно

С уважением.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: странное поведение sizeof
От: Аноним  
Дата: 09.02.06 22:31
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>На платформах, которые допускают работу с невыровненными данными, как правило, существуют платформеннно-зависимые средства для управления выравниванием ('#pragma pack', например). Там обычно можно добиться желаемого тобою равенства. На платформах, где с выравниванием дела обстоят строже, таких средств может и не быть.


Управление выравниванием — это всё-таки скорее свойство не платформы, а компилятора.
Потому что бывает, что компилятор делает структуру упакованной, но обращение к её поям вызывает ошибку (например, SIGBUS на SPARC).
Re[3]: странное поведение sizeof
От: Андрей Тарасевич Беларусь  
Дата: 10.02.06 18:17
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Андрей Тарасевич, Вы писали:


АТ>>На платформах, которые допускают работу с невыровненными данными, как правило, существуют платформеннно-зависимые средства для управления выравниванием ('#pragma pack', например). Там обычно можно добиться желаемого тобою равенства. На платформах, где с выравниванием дела обстоят строже, таких средств может и не быть.


А>Управление выравниванием — это всё-таки скорее свойство не платформы, а компилятора.

А>Потому что бывает, что компилятор делает структуру упакованной, но обращение к её поям вызывает ошибку (например, SIGBUS на SPARC).

Именнно компилятор я и имею в виду под "платформой", т.е. то, что в спецификации языка называется "реализацией" ("implementation"). Формально в С/С++ абсолютно все зависит именно "от компилятора" и практичесики ничего от аппаратной платформы.
Best regards,
Андрей Тарасевич
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.