LINUX.ORG.RU

C, про типы


0

0

вроде все просто, код:
#include <stdio.h>

typedef struct{
        unsigned short int sign;
        unsigned int size;
} header;

int main(int argc, char *argv[]){

    fprintf(stderr, "%d\n", sizeof(unsigned short int));
    fprintf(stderr, "%d\n", sizeof(unsigned int));
    fprintf(stderr, "%d\n", sizeof(header));
    exit(0);
}

в результате получаю:
2
4
8

почему??
anonymous

почитай книжку какую-нибудь, типа 100 частозадаваемых вопросов по Си.

в структуре могут быть дырки. У каждого типа есть alignment requirements. Например int или float можно положить не на любое свободное место в памяти.

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

> Например int или float можно положить не на любое свободное место в памяти.

На x86 можно положить на любое. Alignment делается для повышения производительности.

watashiwa_daredeska ★★★★
()

gcc расширяет структуру для быстрого доступа к членам. Используй __attribute__ ((packed)), чтобы это не работало

Chumka ★★★
()
Ответ на: комментарий от watashiwa_daredeska

при чем тут x86.  Есть стандарт Си.
Код типа:

void *p = (void *)malloc( 1 + sizeof( int ) );
*(int *)((char *)p + 1) = 1;

не удовлетворяет этому стандарту.  Это undefined behaviour.

dilmah ★★★★★
()

Не используй сишные структуры НИКОГДА для компактного хранения данных. Пиши свою сериализацию, если очень надо.

anonymous
()
Ответ на: комментарий от dilmah

> при чем тут x86

При том, что архитектура x86 позволяет размещать данные с любым alignment'ом, просто может быть потеря производительности. В 68000, например, 2-байтовые целые _должны_ быть выровнены на чётный адрес, иначе процессор не сможет с ними работать.

> Код типа:

У тебя есть УЛР на стандарт? У меня стандарта нет. Там явно написано, что этот код - undefined behaviour? Интересно, с какой стати, ведь никакого криминала тут нет?

watashiwa_daredeska ★★★★
()
Ответ на: комментарий от dilmah

компилится однако нормально gcc version 3.3.2

anonymous
()
Ответ на: комментарий от dilmah

>не удовлетворяет этому стандарту. Это undefined behaviour

Это implementation defined behaviour. Чуешь разницу? На некоторых машинах это будет работать без проблем, на других - зто фатальная ошибка.

devinull ★★
()
Ответ на: комментарий от devinull

A pointer to an object can be explicitly converted to a pointer to  an                                                       
  object of different type.61) Except that converting an rvalue of  type                                                       
  "pointer  to  T1"  to  the  type  "pointer to T2" (where T1 and T2 are                                                       
  object types and  where  the  alignment  requirements  of  T2  are  no                                                       
  stricter  than  those  of T1) and back to its original type yields the                                                       
  original pointer value, the result of such  a  pointer  conversion  is                                                       
  unspecified.

То есть не undefined, и не implementation defined, а unspecified.

Абстрактная машина Си является параметризованной.  Да, в некоторых параметризациях
alignment может игнорироваться.

Но корректный код должен быть корректным для любой возможной параметризации
абстрактной машины.

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

А цитата не из стандарта случайно? Если да, то залеё на webfile если не трудно. А то стандарт с++ вчера раздавали, может сегодня СИ перепадет?

devinull ★★
()
Ответ на: комментарий от dilmah

А все-таки, что-то я уже засомневался. В чем разница между unspecified и implementation defined. Разве это не одно и тоже? Если не определено в стандарте, значит опредерено в реализации. Где же еще?

ЗЫ: undefined это обычно что-то типа:

int a[2] = { 0, 0 };

int i = 0;

a[i++]=i++;

Ну, классика короче. Вот это и в самом деле undefined.

devinull ★★
()
Ответ на: комментарий от devinull

> А то стандарт с++ вчера раздавали, может сегодня СИ перепадет?

у меня только драфты. N843 -- август 98, и N1124 -- май 2005. Они публично доступны.

dilmah ★★★★★
()
Ответ на: комментарий от devinull

> А все-таки, что-то я уже засомневался.

ну в общем я понимаю так.  В той фразе шла речь всего лишь
о приведении одного указателя к другому.
Тут unspecified -- это ничего страшного.

Мы обсуждали не собственно приведение, а использование
объекта по невыровненному адресу.

Тут есть такие слова:

The lifetime of an object is a runtime property of  the  object.   The                                                       
  lifetime of an object of type T begins when:                                                                                 
                                                                                                                               
  --storage  with  the proper alignment and size for type T is obtained,                                                       
    and
  ...

(char *)p + 1 не является storage with proper alignment для инта (для произвольной
параметризации абс. машины).
Значит lifetime объекта по этому адресу не начался.  Значит с ним нельзя проводить операции.

Это все было про С++.

В стандарте Си так написано:

A  pointer  to  an  object  or  incomplete type may be                                                            
converted to a pointer to a different object  or  incomplete                                                            
type.   If the resulting pointer is not correctly aligned48)                                                            
for  the  pointed-to  type,  the  behavior   is   undefined.

dilmah ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.