Ошибки, баги, вопросы - страница 2501

 
fxsaber:

Не помню, в документации об этом есть.

Спасибо, нашёл. На мой взгляд всё работает. Поскольку в вашем примере только один тип в структуре, то и выравнивать нет смысла. Потому и даёт размер только типа. А вот так получается

struct A pack(4)
{
  short j;
  int   z;
};

void OnStart()
{
  Print(sizeof(A)); // 8
}

А такая структура

struct A pack(8)
{
  short   j;
  double  x;
  int     b;
};

void OnStart()
{
  Print(sizeof(A)); // 24
}

В документации очень наглядно объясняется в картинках.


 
Alexey Viktorov:

Спасибо, нашёл. На мой взгляд всё работает. Поскольку в вашем примере только один тип в структуре, то и выравнивать нет смысла. Потому и даёт размер только типа. А вот так получается

А такая структура

В документации очень наглядно объясняется в картинках.


да, так работает:

const uint FFFF=0xFFFFFFFF;
//+------------------------------------------------------------------+
union UnionCheckByte
  {
   uint              byte_4x4[4];
   struct uA pack(4) {ushort j1; ulong j2; } a;
   struct uB pack(8) {ushort j1; ulong j2; } b;
  };
//+------------------------------------------------------------------+
void OnStart()
  {
   UnionCheckByte tst;
   tst.byte_4x4[0]=FFFF;   tst.byte_4x4[1]=FFFF;   tst.byte_4x4[2]=FFFF;   tst.byte_4x4[3]=FFFF;   // заполним память 0xFFFFFFFF FFFFFFFF
   ArrayPrint(tst.byte_4x4);
// A   
   Print("A:");
   tst.byte_4x4[0]=FFFF;   tst.byte_4x4[1]=FFFF;   tst.byte_4x4[2]=FFFF;   tst.byte_4x4[3]=FFFF;   // заполним память 0xFFFFFFFF FFFFFFFF
   
   ZeroMemory(tst.a);
   ArrayPrint(tst.byte_4x4);
   
// B
   Print("B:");
   tst.byte_4x4[0]=FFFF;   tst.byte_4x4[1]=FFFF;   tst.byte_4x4[2]=FFFF;   tst.byte_4x4[3]=FFFF;   // заполним память 0xFFFFFFFF FFFFFFFF
   ZeroMemory(tst.b);
   ArrayPrint(tst.byte_4x4);
 
   Print("sizeof(A) = ",sizeof(tst.a)," , sizeof(B) = ",sizeof(tst.b));
  }
//+------------------------------------------------------------------+

2019.07.07 19:16:27.100 tst (EURUSD,H1) 4294967295 4294967295 4294967295 4294967295

2019.07.07 19:16:27.100 tst (EURUSD,H1) A:

2019.07.07 19:16:27.100 tst (EURUSD,H1)          0          0          0 4294967295

2019.07.07 19:16:27.100 tst (EURUSD,H1) B:

2019.07.07 19:16:27.100 tst (EURUSD,H1) 0 0 0 0

2019.07.07 19:16:27.100 tst (EURUSD,H1) sizeof(A) = 12 , sizeof(B) = 16



итого: pack() выполняет выравнивание данных в структуре на размер максимального sizeof() поля структуры

 
Igor Makanu:

итого: pack() выполняет выравнивание данных в структуре на размер максимального sizeof() поля структуры

Не совсем так.

struct A pack(4)
{
  short   j;
  double  x;
  int     b;
};

void OnStart()
{
  Print(sizeof(A)); // 16
}

максимальное поле 8 байт, задали выравнивание 4 и получили 16. То-есть 2+2|4|2+2|2+добавка short doubleint

Или 2+добавка|4|4|4

 
Alexey Viktorov:

Не совсем так.

максимальное поле 8 байт, задали выравнивание 4 и получили 16. То-есть 2+2|4|2+2|2+добавка short doubleint

Или 2+добавка|4|4|4

да, тогда наверное так корректно звучать должно:

итого: pack() выполняет выравнивание данных в структуре поэлементно , каждый элемент будет дополнен  значением кратным  pack()  с учетом  максимального sizeof() элемента  структуры  (не более максимального значения, менее может быть при дополнении)

pack(4)  :

short   = 2 + 2 дополним  = 4   = pack(4) 

double  = 8 -  не выравниваем

int = 4   - не выравниваем

sizeof() = 16   байт

 
Igor Makanu:

да, тогда наверное так корректно звучать должно:

итого: pack() выполняет выравнивание данных в структуре поэлементно , каждый элемент будет дополнен  значением кратным  pack()  с учетом  максимального sizeof() элемента  структуры  (не более максимального значения, менее может быть при дополнении)

pack(4)  :

short   = 2 + 2 дополним  = 4   = pack(4) 

double  = 8 -  не выравниваем

int = 4   - не выравниваем

sizeof() = 16   байт

Замудрёно звучит, но мне понятно.)))

 
Alexey Viktorov:

Замудрёно звучит, но мне понятно.)))

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

fxsaber, 2019.07.07 15:03

от порядка полей зависит потребление памяти и, видимо, производительность.

Пока не смог до конца понять.

 
fxsaber:

Пока не смог до конца понять.

Не от порядка полей, а от максимального и заданного значения pack() плюс зависит от последовательности полей.

Вот сейчас сделал ещё такой вариант

struct A pack(16)
{
  short   j;
  double  x;
  int     b;
};

void OnStart()
{
  Print(sizeof(A)); // 24
}

получилось выравнивание не до 16 как указано в pack(), а до 8 по максимальному double.

 
Alexey Viktorov:

плюс зависит от последовательности полей. 

проверил, действительно зависит:

struct A pack(16)
{
  double  x;
  short   j;
  int     b;
};
//+------------------------------------------------------------------+
void OnStart()
  {
   Print(sizeof(A)); // 16
  }
//+------------------------------------------------------------------+
Ваш пример выдал  sizeof(A) = 24
 
fxsaber:

Так с этого и началось данное обсуждение. Оказалось, что все совсем не так.

Да, я ошибся в описании алгоритма выравнивания и тем самым возможно внес еще больше сумятицы.

Итак

pack это механизм совместимости с внешними длл. в частности аналог с++ #pragma pack. и поэтому работать должен тоже аналогично.

дальше примеры с размерами (для pack 4)

char -> 1

short -> 2

int -> 4

long -> 8

char, short -> 4

char, int -> 8

char, long -> 12 (16 для pack(8))

short, char -> 4

long, char -> 12

long, char, short -> 12

long, char, char, char -> 12

long, char, int -> 16

long, char, int, char -> 20

по умолчанию у студии (да и везде наверное) стоит pack(8)
 
TheXpert:

Спасибо, понял.