Когнитивный диссонанс

Вчера я был поражен на столько, что усомнился в том, во что верил уже лет 10. А именно в том, что при выравнивании 8, размер структур с полями {u64, u32, u16} и {u8, u32, u16} будет одинаков, т.е. равен 16. А ведь приложение собранное Rust утверждает что в первом случае размер 16, что и следовало ожидать, а во втором 12(!!!).

type tuple_type1 = (u64, u32, u16);
type tuple_type2 = (u8, u32, u16);

fn main() {
    io::println(#fmt("size of tuple_type1 = %u, size of tuple_type2 = %u",
        sys::size_of::<tuple_type1>(), sys::size_of::<tuple_type2>()));
    io::println(#fmt("align of tuple_type1 = %u, align of tuple_type2 = %u",
        sys::align_of::<tuple_type1>(), sys::align_of::<tuple_type2>()));
}

Содержимое консоли:

> ./main
size of tuple_type1 = 16, size of tuple_type2 = 12
align of tuple_type1 = 8, align of tuple_type2 = 8


Я бал поражен на столько, что полез в C++:

#include <iostream>
#include <stdint.h>

struct struct1 {
    uint8_t v1;
};

struct struct2 {
    uint8_t v1;
    uint32_t v2;
    uint16_t v3;
};

struct struct3 {
    uint64_t v1;
    uint32_t v2;
    uint16_t v3;
};

int main()
{
    std::cout << "sizeof struct1 = " << sizeof(struct1) << std::endl
        << "sizeof struct2 = " << sizeof(struct2) << std::endl
        << "sizeof struct3 = " << sizeof(struct3) << std::endl;

    return 0;
}

Но тут мне стало совсем плохо:

sizeof struct1 = 1
sizeof struct2 = 12
sizeof struct3 = 16

И только после такого эксперимента становится очевидно, что мир сума не сошел, и все нормально:

#include <iostream>
#include <stdint.h>

struct struct1 {
    uint8_t v1;
} __attribute__((aligned(8)));

struct struct2 {
    uint8_t v1;
    uint32_t v2;
    uint16_t v3;
} __attribute__((aligned(8)));

struct struct3 {
    uint64_t v1;
    uint32_t v2;
    uint16_t v3;
} __attribute__((aligned(8)));

int main()
{
    std::cout << "sizeof struct1 = " << sizeof(struct1) << std::endl
        << "sizeof struct2 = " << sizeof(struct2) << std::endl
        << "sizeof struct3 = " << sizeof(struct3) << std::endl;

    return 0;
}

Содержимое консоли:

sizeof struct1 = 8
sizeof struct2 = 16
sizeof struct3 = 16

Ну а если говорить насчет Ржавчины, то в рассылке сказали что, это, похоже, ошибка в функции align_of.

Leave a Reply