FreeBasic
Главная
Вход
Регистрация
Понедельник, 17.08.2026, 01:31Приветствую Вас Гость | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Размер структуры не равен сумме размеров её полей
zamabuvaraeuДата: Суббота, 02.05.2026, 12:51 | Сообщение # 1
Полковник
Группа: Друзья
Сообщений: 219
Репутация: 5
Статус: Offline
Программисты используют структуры, в конце которых расположен массив переменного размера. Эта структура и выделение памяти для неё может выглядеть следующим образом:
Код
Type MyPointersArray
   Length As Long
   Vector(0) As Any Ptr
End Type

Dim WrongSize As UInteger = SizeOf(Long) + 5 * SizeOf(Any Ptr)

Dim p As MyPointersArray Ptr = Allocate(WrongSize)
Этот код будет корректно работать в 32-битном варианте, однако его 64-битный вариант покажет крах. При выделении памяти, необходимой для хранения объекта типа `MyPointersArray`, содержащего 5 указателей, необходимо учесть, что начало массива `Vector` будет выровнено по границе 8 байт. Расположение данных в памяти на разных системах (Win32/Win64) выглядит так.

Для 32‐бит:

Код
Length
Vector(0)
Vector(1)
Vector(2)
Vector(3)
Vector(4)

Для 64‐бит:


Код
Length
alignment     <--- выравнивание
Vector(0)
Vector(1)
Vector(2)
Vector(3)
Vector(4)


Правильный расчёт размера должен выглядеть следующим образом:


Код
Dim RealSize As UInteger = OffsetOf(MyPointersArray, Vector(0)) + 5 * SizeOf(Any Ptr)

В приведённом коде мы узнаём смещение последнего члена структуры и суммируем это смещение с его размером. Смещение члена структуры или класса можно узнать с использованием макроса `OffsetOf`. Всегда используйте макрос `OffsetOf` для получения смещения в структуре, не опираясь на свои предположения о размерах типов и правилах их выравнивания.
 
DarkDemonДата: Суббота, 02.05.2026, 16:56 | Сообщение # 2
Генерал-майор
Группа: Друзья
Сообщений: 345
Репутация: -1
Статус: Offline
Никогда не пользовался подобными UDT. Привык делать проще. Чем проще делаешь - тем меньше потом гемороя.

FIELD = 1 не помогает?
 
zamabuvaraeuДата: Суббота, 02.05.2026, 18:42 | Сообщение # 3
Полковник
Группа: Друзья
Сообщений: 219
Репутация: 5
Статус: Offline
Указатели должны быть выровнены, поэтому FIELD тут будет вредить.
 
DarkDemonДата: Суббота, 02.05.2026, 22:09 | Сообщение # 4
Генерал-майор
Группа: Друзья
Сообщений: 345
Репутация: -1
Статус: Offline
Цитата zamabuvaraeu ()
Указатели должны быть выровнены, поэтому FIELD тут будет вредить.

Распредели руками. Не делай одну UDT на все случаи жизни. FIELD можно самому задавать, на сколько надо выравнивать.
Слышал краем уха что местами надо и на 16 выравнивать(если SIMD используются), там щас в железе много всяких фентиклюх,
мозгов столько нет чтобы всё это использовать. По сути оптимизация это не вопрос рефакторинга и удобства кодера.

Твоя тема косвенно подтверждает, что кроссплатформа на FB - закончилась. Это конечно не ошибка компиля, он выравнивает
как ему удобно, но это всё нюансы, очень тонкие, очень мелкие и по пустякам озадачивающие людские головы.
Сам уже давно(с самого начала кодинга на FB) прописываю всегда FIELD = 1, чтобы не было "сюрпризов", потому
что уже ловил говно с этим связанное. Самое основное чтобы прога работала, а как там уже оптимизировать - дело десятое.

К тому же сейчас по сути всё поломали, касаемо монополии x86-x64. Оптимизация так-то никогда лёгким делом не была.
Если раньше это было первостепенно из-за доминирования x86 архитектуры, то сейчас просто смута. Ну как бы надо, да
но это не главное.

Cтараюсь писать BASIC код, который сам по себе будет максимально переносимым. Т.е. по сути самая база QB.
И все вот эти синтаксич. сахара, ну да они там что-то дают, но по сути и код сложнее читать и переносимость уже
не такая быстрая, да и все эти штуки нюансы держать в голове - инсульт хватит, без этого есть о чём подумать.
 
  • Страница 1 из 1
  • 1
Поиск: