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

 
Andrei Trukhanovich:

смысл выравнивания в том, чтобы адреса внутренних переменных были кратны выравниванию.

Попытался сопоставить Ваше утверждение и Документацию, но так и не понял.

[Удален]  
Andrei Trukhanovich:

Недопиленная штука, видимо. Ведь тут то уже явно ошибка:

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

void OnStart()
{
   A q[2];
   Print(sizeof(q)); // 4
   return;
}
 
fxsaber:

Попытался сопоставить Ваше утверждение и Документацию, но так и не понял.

по моему справка не обновлена, вроде в билде в котором появилась поддержка C# (зимой? ) было описание как теперь работает выравнивание

вот статью на хабре нагуглил, про выравнивание, по моему сейчас так же в МТ5 будет работать https://habr.com/ru/post/142662/

 
Igor Makanu:

по моему справка не обновлена, вроде в билде в котором появилась поддержка C# (зимой? ) было описание как теперь работает выравнивание

вот статью на хабре нагуглил, про выравнивание, по моему сейчас так же в МТ5 будет работать https://habr.com/ru/post/142662/

Провел статью и комментарии к ней. Совсем не понятент алгоритм выравнивания. Стоит pack(4), но почему-то что-то выравнивается до 2-х, что-то до 4-х.

[Удален]  
fxsaber:

Провел статью и комментарии к ней. Совсем не понятент алгоритм выравнивания. Стоит pack(4), но почему-то что-то выравнивается до 2-х, что-то до 4-х.

А чего заморачиваться? Единичное выравнивание по-умолчанию как и раньше (и вряд ли изменится), спецификатор pack - кривой. Если очень надо, то можно вставить добивку самому.

 
Vict:

А чего заморачиваться? Единичное выравнивание по-умолчанию как и раньше (и вряд ли изменится), спецификатор pack - кривой. Если очень надо, то можно вставить добивку самому.

Хочется разобраться.

 
fxsaber:

Хочется разобраться.

выравнивание данных это не 

Print(sizeof(A)); // 2

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

выравнивание это расположение данных в физической памяти, как и написано в справке " для передачи в импортированные dll-функции" - в различных компиляторах и в языках типы данных могут отличаться по своим размерам или вернее по способу хранения в памяти, вот и нужно использовать struct A pack(4) чтобы каждый член структуры "не вылез за свою клеточку" - байты 

вот как на хабре в статье:

struct Foo
{
    char ch;
    int value;
};

1 байт: ch

2 байт: пусто

3 байт: пусто                                        ЭТО  char ch;  

4 байт: пусто


5 байт: value[0]

6 байт: value[1]                                   ЭТО   int value;     

7 байт: value[2]

8 байт: value[3]


 
Igor Makanu:

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

Это не так

struct A pack(4)
{
  short j;
  char i;
};

void OnStart()
{
  Print(sizeof(A)); // 4
}
 
fxsaber:

Это не так

тогда Ваш пример проверил что sizeof() корректно посчитал "вес" структуры в байтах,

остается только физическую память проверить, но по моему будет только при вызове dll работать, не факт что разработчики не заоптимизировали хранение данных в памяти ;) - т.е. если не используется pack(4) по назначению в коде, то может он быть и проигнорирован в исполняемом коде

 
Igor Makanu:

тогда Ваш пример проверил что sizeof() корректно посчитал "вес" структуры в байтах

Поэтому и возникает вопрос, как на самом деле работает выравнивание? Документация и Хабр своими примерами не раскрыли алгоритм.

Igor Makanu:

остается только физическую память проверить, но по моему будет только при вызове dll работать, не факт что разработчики не заоптимизировали хранение данных в памяти ;) - т.е. если не используется pack(4) по назначению в коде, то может он быть и проигнорирован в исполняемом коде

В физической памяти аналогично.
struct A pack(4)
{
  short j;
  char i;
};

void OnStart()
{
  Print(sizeof(A)); // 4
  
  const int handle = FileOpen(__FILE__, FILE_WRITE | FILE_BIN);
  
  if (handle != INVALID_HANDLE)
  {
    A a = {0};
    
    FileWriteStruct(handle, a);
    Print(FileTell(handle)); // 4
    
    FileClose(handle);
  }
}