nixp.ru v3.0

26 мая 2017,
пятница,
08:44:48 MSK

DevOps с компанией «Флант»
Fatal написал 14 октября 2004 года в 14:18 (340 просмотров) Ведет себя как мужчина; открыл 123 темы в форуме, оставил 484 комментария на сайте.

Почему структура 'A' занимает 6 байт, тогд как short + char + char = 4

А структуры 'B,’C',’D' столько сколько им положено?

struct A{

char _1;

short _2;

char _3;

};

struct B{

char _1;

};

struct C{

char _1;

char _2;

};

struct D{

char _1;

char _2;

char _3;

};

struct A func(int*a,int *b,int*c){

struct A sa={1,2,3};

*a=99,*b=19,*c=22;

return sa;

}

main(){

printf(

«size_A=%ld,size_B=%ld,size_C=%ld,size_D=%ld\n»

,sizeof(struct A),sizeof(struct B),sizeof(struct C),sizeof(struct D)

);

}

semka

Некоторые компиляторы для удобства вычислений и передачи данных на уровне процессора вообще не отличают short от char или byte от int.

xant

У меня выдается, что структура A занимает 4 байта.

vnp


struct A{
 char _1;
 short _2;
 char _3;
};

Компилятор обязан разместить short_2 по четному адресу; для этого после char_1 он вставит прокладку (padding) в 1 байт. Сами структуры должны размещаться тоже по четным адресам (тоже ради short), поэтому в конце структуры тоже будет добавлен выравнивающий байт. Два лишних байта, итого 6.

Для минимизации паддинга, компилятор имеет право переставлять элементы структуры. В версии Xant они, видимо, видимо, расставились в порядке short_2, char_1, char_3. Все зависит от компилятора и уровня оптимизации.

Fatal

[quote author=vnp link=board=coding;num=1097749116;start=0#3 date=10/14/04 в Компилятор обязан разместить short_2 по четному адресу; для этого после char_1 он вставит прокладку (padding) в 1 байт. Сами структуры должны размещаться тоже по четным адресам (тоже ради short), поэтому в конце структуры тоже будет добавлен выравнивающий байт. Два лишних байта, итого 6.

Для минимизации паддинга, компилятор имеет право переставлять элементы структуры. В версии Xant они, видимо, видимо, расставились в порядке short_2, char_1, char_3. Все зависит от компилятора и уровня оптимизации. [/quote]

Как я понял в связи с этим, невозможно писать функции на асемблере, т.к. расположение полей зависит от компилятора и узнать смещение поля просто не возможно.

vnp
Fatal
Как я понял в связи с этим, невозможно писать функции на асемблере, т.к. расположение полей зависит от компилятора и узнать смещение поля просто не возможно.

Короткий ответ — не стоит.

Если очень нужно, можно попробовать

а) вручную располагать поля структуры в порядке убывания требований к выравниванию

б) применять #pragma pack или __attribute__((packed)) (будет работать на x86, но прямая дорога к сегфолтам на 68K)

в) что-то в духе

struct A {
    char char_1;
    char short_2[2];
    char char_3;
};
vnp

В догонку:

Совсем правильный способ — написать утилиту, которая по .h строила бы .i. Однажды делал такое. Ничего военного — связка gcc -g -S и несложного скрипта на awk/perl/tcl/whatewer.

Fatal

ОК, Спасибо

Fatal
vnp
В догонку:

Совсем правильный способ — написать утилиту, которая по .h строила бы .i. Однажды делал такое. Ничего военного — связка gcc -g -S и несложного скрипта на awk/perl/tcl/whatewer.

Зачем переводить .h файлы в .i?

макрос define поддерживается компилятором as, а все остальное просто не нужно

vnp
Fatal
Зачем переводить .h файлы в .i?

макрос define поддерживается компилятором as, а все остальное просто не нужно

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

Fatal
vnp
Именно для того, чтобы разворачивать определения структур в набор смещений. Мы же с этого начали, верно?

Интересно, как может помочь в этом заголовочный файл, если там содержаться только объявления для компилятора или команды для препоцессора?

vnp
Fatal
Интересно, как может помочь в этом заголовочный файл, если там содержаться только объявления для компилятора или команды для препоцессора?

А вы определения структур где держите?

Fatal
vnp
А вы определения структур где держите?

Если вы про асм, то нигде. А для си — в заголовочных файлах, конечно же.

athilson

Если я правильно понял суть, то этого можно избежать так:

#pragma pack(1)

struct {

char _1;

short _2;

} align;

#pragma pack()

struct {

char _1;

short _2;

} asis;

printf(«%d\n%d\n», sizeof(align), sizeof(asis));

Вывод:

3

4

Компилятор: gcc 3.2.3

Fatal

А что означает #pragma pack(), если не секрет?

athilson

/* выравнивать по границе байта */

#pragma pack(1)

/* включить режим выравнивания по умолчанию (обычно по границе слова, зависит от платформы) */

#pragma pack()

Fatal

значат то что внизу этих макросов, то все выравнивается соответствующим образом, так?

athilson

да, так.