@AHMED_RAPIRA

Почему типы полей структуры в качестве указателя не соответствуют своим размерам в памяти (target wasm32)?

имеется такая структура:

#[repr(C)]
struct Test {
    pub a: usize,
    pub b: u8,
    pub c: u8,
    pub d: usize,
}


repr(C) указывает, что поля идут по порядку - ок.
имеется такой код:

#[no_mangle]
pub fn test() {
    let ptr = 10 as *mut Test;

    unsafe {
        (*ptr).a = 1;
        (*ptr).b = 2;
        (*ptr).c = 3;
        (*ptr).d = 4;
    }
}


когда я собираю его в target wasm32-unknown-unknown, получаю такую функцию в wasm:

(func (;0;) (type 0) (param i32)
  ;; (*ptr).a = 1
  ;; здесь правильно - указатель был на 10
  i32.const 10
  i32.const 1
  i32.store
  ;; (*ptr).b = 2
  ;; тоже правильно - usize предыдущего поля "a" равен интервалу в 4 байта, указатель на 10 + 4 = 14
  i32.const 14
  i32.const 2
  i32.store8
  ;; (*ptr).c = 3
  ;; тоже правильно - u8 предыдущего поля "b" равен интервалу в 1 байт, указатель на 14 + 1 = 15
  i32.const 15
  i32.const 3
  i32.store8
  ;; (*ptr).d = 4
  ;; а вот тут не правильно - почему произошел перескок на 18 а не на 16 ??
  i32.const 18
  i32.const 4
  i32.store)


почему при указании u8 у меня указатель смещается не на 1 байт для поля "d"?
  • Вопрос задан
  • 140 просмотров
Решения вопроса 1
Vindicar
@Vindicar
RTFM!
Выравнивание по 32 бита.
Некоторые архитектуры процов вообще требуют, чтобы целое размером N байт имело адрес кратный N.

Для других это не обязательно, но доступ по адресам, кратным разрядности, быстрее. Так что компиляторы часто вставляют неиспользуемые байты в структуру, чтобы подвинуть следующее поле на "удобный" адрес. В плюсах (а может и в си) вроде есть директива #pragma pack, которая эти м управляет. Насчёт раста не знаю.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы