C++11的alignof和alignas

我曾经在文章C++结构体字节对齐icon-default.png?t=M276https://blog.csdn.net/iaibeyond/article/details/48971563

讨论过C++的相关字节对齐问题。C++11带来了两个关键字alignof和alignas。

alignof(Type),用于获取类型的对齐字节数。

alignas(number) Type,用于改变目标类型的对齐字节数。

它们直观的区别是alignof是get,alignas是set。有些同学在开始记忆的时候可能会混淆alignof和alignas,一个简单的记忆方式是把单词拆开理解,align of Type,即Type的对齐字节数;align as number ,即把字节数当做(as) number。这样就不会记错了。

关于alignof格外要注意的一点是,它只能用于操作类型,不能操作变量。sizeof则不同,既可以操作类型,也可以操作变量。

struct A
{
	int a;
	int b;
	A()
	{
		cout << "alignof(int) = " << alignof(int) << endl;
		cout << "alignof(b) = " << alignof(b) << endl; //编译错误!alignof只能操作类型,不能操作变量!

		cout << "sizeof(int) = " << sizeof(int) << endl;
		cout << "sizeof(b) = " << sizeof(b) << endl; //OK!sizeof既能操作类型,也能操作变量!
	}
};

alignas,主要有以下3个应用场景

1、修改结构体的对齐依据。 

struct stTestAlign
{
	char a;
	char b;
	stTestAlign()
	{
		cout << "sizeof(stTestAlign) =" << sizeof(stTestAlign) << endl;    //2
		cout << "alignof(stTestAlign) =" << alignof(stTestAlign) << endl;  //1
	}
};

stTestAlign在没有使用alignas的情况下,sizeof=2,alignof=1

struct alignas(4) stTestAlign
{
	char a;
	char b;
	stTestAlign()
	{
		cout << "sizeof(stTestAlign) =" << sizeof(stTestAlign) << endl;    //4
		cout << "alignof(stTestAlign) =" << alignof(stTestAlign) << endl;  //4
	}
};

现在使用alignas(4)指定stTestAlign对齐依据为4,则sizeof=4,alignof=4。

2、修改结构体内部变量的对齐依据。

struct stTestAlign
{
	char a;
	alignas(4) char b;
	stTestAlign()
	{
		cout << "sizeof(stTestAlign) =" << sizeof(stTestAlign) << endl;   //8
		cout << "alignof(stTestAlign) =" << alignof(stTestAlign) << endl; //4
	}
};

我们要求char b的对齐依据为4,那么最终 sizeof(stTestAlign)=8,alignof(stTestAlign)=4

这里有个问题,如果变量添加了alignas,结构体也添加了alignas,那么结构体的最终对齐依据是谁呢?

这个其实和默认的对齐规则一样,两者取其大。

struct alignas(2) stTestAlign
{
	char a;
	alignas(4) char b;
	stTestAlign()
	{
		cout << "sizeof(stTestAlign) =" << sizeof(stTestAlign) << endl;   //8
		cout << "alignof(stTestAlign) =" << alignof(stTestAlign) << endl; //4
	}
};

3、修改单独变量的对齐依据。

这个其实和第2条类似,第2条的变量在结构体内部,而这里变量不在结构体内。

alignas(number) Type variable;意思是:给变量variable分配地址的时候,它的地址要是number的整数倍,即地址要对齐number。

	int a;
	cout << (int)(&a) % 16 << endl;

int默认以4对齐,则a的地址对16取模,可能是0 4 8 12。

	alignas(16) int a;
	cout << (int)(&a) % 16 << endl;

此时我们强制a向16对齐,则a的地址对16取模,只能是0,因为它的地址一定是从16的整数倍开始的嘛!

需要注意的有:

  1. alignas只能往大对齐,不能往小对齐,如果类型本身的对齐依据是4,那么alignas(2)则不起效!即它不能起到#pragma pack的作用!如果想往小对齐,只能使用pragma pack。
  2. __declspec(align(4))也是指定往大对齐,它和alignas(4)有什么区别?alignas是C++语言级别的标准,而__declspec则是Microsoft自己添加的扩展。它们在使用方式上有区别,但起到的作用是一样的,都是为了往大对齐。既然已经有一个能起到往大对齐的__declspec(align())了,为什么还要加个alignas?猜测原因是为了提高使用的精准性,__declspec有很多用途,__declspec(align())只是它的用途之一,而加了alignas则专门用于字节对齐。这个出发点和C++11引入匿名命名空间有点像,是为了取代static,成为专门处理文件静态变量的手段;而alignas则是专门处理字节对齐的手段。
### 回答1: alignas是一个C++11中的关键字,用于指定变量或类型的对齐方式,即在内存中占用的字节数。 alignof是一个C++11中的运算符,用于获取变量或类型的对齐方式,即在内存中占用的字节数。 总结:alignas是设置对齐方式,alignof是查询对齐方式。 ### 回答2: alignasalignof是在C++11引入的两个关键字,主要用于控制内存对齐。 首先,alignas是一个类型或对象的属性修饰符,通过它可以指定某个类型或对象在内存中的对齐方式。它可以用于类、结构体、联合体类型别名,也可以用于变量、数组函数。通过在声明时使用alignas关键字加上对齐值,可以强制该类型或对象按照指定对齐值进行内存对齐,而不再使用默认的对齐方式。比如,使用alignas(16)可以将一个对象的对齐方式设置为16字节对齐。 其次,alignof是一个运算符,用于获取一个类型或对象的对齐方式。通过在类型或对象前使用alignof运算符,可以得到该类型或对象在内存中的对齐值。比如,使用alignof(int)可以得到int类型在内存中的对齐值。 综上所述,alignas用于指定类型或对象的对齐方式,而alignof用于获取类型或对象的对齐值。alignas主要用于修饰,alignof主要用于获取。它们都是在C++11中引入的关键字,用于更精确地控制内存对齐,提高程序的性能效率。 ### 回答3: alignasalignofC++11中引入的两个关键字,用于控制内存对齐方式。 alignas关键字用于指定对象在内存中的对齐方式,可以被用于类型、对象函数声明。通过使用alignas,我们可以要求编译器将特定的对象按照指定的对齐方式进行内存布局。例如,我们可以使用alignas(16)来要求一个对象按照16字节对齐方式对齐。 而alignof关键字用于获取对象在内存中的对齐方式。它返回一个常量表达式,表示类型或对象要求的对齐方式。例如,alignof(int)返回的值通常是4,表示int类型通常要求按照4字节对齐。 总结起来,alignas用于指定对齐方式,alignof用于获取对齐方式。alignas是一个用于编译期的关键字,可以在声明时使用,而alignof则是一个运行时的操作符,用于获取实际的对齐方式。 需要注意的是,使用alignasalignof关键字可能会影响程序的性能可移植性,因为对齐方式的改变可能会导致内存访问的效率降低,或者在某些平台上出现未定义行为。因此,使用这两个关键字时需要谨慎,并充分了解目标平台的内存对齐机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值