sizeof和alignof有什么区别?
#include <iostream>
#define SIZEOF_ALIGNOF(T) std::cout<< sizeof(T) << '/' << alignof(T) << std::endl
int main(int, char**)
{
SIZEOF_ALIGNOF(unsigned char);
SIZEOF_ALIGNOF(char);
SIZEOF_ALIGNOF(unsigned short int);
SIZEOF_ALIGNOF(short int);
SIZEOF_ALIGNOF(unsigned int);
SIZEOF_ALIGNOF(int);
SIZEOF_ALIGNOF(float);
SIZEOF_ALIGNOF(unsigned long int);
SIZEOF_ALIGNOF(long int);
SIZEOF_ALIGNOF(unsigned long long int);
SIZEOF_ALIGNOF(long long int);
SIZEOF_ALIGNOF(double);
}
Run Code Online (Sandbox Code Playgroud)
将输出
1/1 1/1 2/2 2/2 4/4 4/4 4/4 4/4 4/4 8/8 8/8 8/8
我想我不知道对齐是什么......?
考虑这个简单的程序
#include <iostream>
struct A
{
int x1234;
short x56;
char x7;
};
struct B : A
{
char x8;
};
int main()
{
std::cout << sizeof(A) << ' ' << sizeof(B) << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这打印8 12.即使B可以在不破坏对齐要求的情况下打包成8个字节,但它却占用了贪婪的12个字节.
这样会很好sizeof(B) == 8,但答案是结构的大小是否必须
是该结构对齐的精确倍数?表明没有办法.
因此,当以下时我感到惊讶
struct MakePackable
{
};
struct A : MakePackable
{
int x1234;
short x56;
char x7;
};
struct B : A
{
char x8;
};
Run Code Online (Sandbox Code Playgroud)
印刷8 8 …
alignof(char)除了1之外什么都可以吗?
最弱(最小)的对准是种类的排列
char,signed char以及unsigned char,它通常是1.
"通常"似乎意味着它可能是别的东西.
C标准关于对齐的唯一规定char是(C11 N1570 6.2.8第1段):
可以使用
_Alignof表达式查询完整类型的对齐要求.类型char,signed char和,unsigned char应具有最弱的对齐要求.
但是,请考虑对齐的定义(C11 N1570 6.2.8第1段,并为C++ 11定义类似):
对齐是实现定义的整数值,表示可以分配给定对象的连续地址之间的字节数.
从这一点来看,我不认为对齐是有意义的,char但1由于要求sizeof(char) ? 1,这意味着相邻char元素之间的距离只能是1字节.
这有意义吗?
我创建了三个几乎相同的枚举:
#[derive(Clone, Debug)]
pub enum Smoller {
Int(u8),
Four([u8; 4]),
Eight([u8; 8]),
Twelve([u8; 12]),
Sixteen([u8; 16]),
}
#[derive(Clone, Debug)]
pub enum Smol {
Float(f32),
Four([u8; 4]),
Eight([u8; 8]),
Twelve([u8; 12]),
Sixteen([u8; 16]),
}
#[derive(Clone, Debug)]
pub enum Big {
Float(f64),
Four([u8; 4]),
Eight([u8; 8]),
Twelve([u8; 12]),
Sixteen([u8; 16]),
}
pub fn main() {
println!("Smoller: {}", std::mem::size_of::<Smoller>()); // => Smoller: 17
println!("Smol: {}", std::mem::size_of::<Smol>()); // => Smol: 20
println!("Big: {}", std::mem::size_of::<Big>()); // => Big: 24
}
Run Code Online (Sandbox Code Playgroud)
鉴于对计算机和内存的了解,我期望它们的大小应相同。最大的变体是[u8; 16]大小为16的。因此,尽管这些枚举的第一个变体的大小确实有所不同,但它们具有的最大变体的大小相同,并且变体总数相同。
我知道Rust可以做一些优化来确认某些类型何时存在间隙(例如,指针会折叠,因为我们知道它们将无效且为0),但这确实是相反的。我认为,如果我是手工构造此枚举,我可以将其装入17个字节(辨别只需要一个字节),因此20个字节和24个字节都让我感到困惑。 …
T我明确指定为x -aligned的类型sizeof(T)假设我现在有:T arr[y],其中arr是X -aligned(无论是通过被分配在堆栈上,或者在数据,或由X -aligned堆分配)
然后至少有一些arr[1],...,arr[y-1]不是x对齐的.
正确?(事实上,如果不随扩展对齐规范改变,它必须是正确的sizeof(T))
注1:这是不一样的问题是如何的阵列在C++对准相比包含一个类型?.这个问题询问阵列本身的对齐方式,而不是内部各个元素的对齐方式.
注2:这个问题:alignas会影响sizeof的值吗?基本上就是我要问的 - 但是对于扩展对齐.
注3:https://stackoverflow.com/a/4638295/7226419 这个问题是一个权威的答案(sizeof(T)包括满足对齐要求所需的任何填充,以使所有T的数组T正确对齐.