Вчера я был поражен на столько, что усомнился в том, во что верил уже лет 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>()));
}
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
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;
}
#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
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;
}
#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
sizeof struct2 = 16
sizeof struct3 = 16
Ну а если говорить насчет Ржавчины, то в рассылке сказали что, это, похоже, ошибка в функции align_of.