需要说明的是,本文讨论的是对象的首地址对齐问题,而不是对象大小的对齐。

变量首地址对齐

可以使用_Alignas(n)指定变量的首地址对齐,其中n必须是2的幂次方。

例如,以下语句指定变量x首地址按照128字节对齐:

_Alignas(128) int x[10];

线程本地变量的首地址对齐

可能我们想当然地认为线程本地变量的首地址对齐是这样的:

__thread _Alignas(128) int x[10];

经验证,这种方式只适用于主线程,子线程就失效了。

验证用例:

snippet.c
#include <stdlib.h>
#include <stdio.h>
#include <sys/resource.h>
#include <pthread.h>
 
__thread _Alignas(512) int x[10];
 
void sub(void* args)
{
	printf("sub:  %p\n", &x[10]);
}
 
int main()
{
	printf("main: %p\n", &x[10]);
	pthread_t tid;
	pthread_create(&tid, NULL, sub, NULL);
	ptrhead_join(tid, NULL);
	return 0;
}

编译运行:

snippet.bash
[yz@test ~]$ gcc -lpthread test.c -o test
[yz@test ~]$ ./test
main: 0x7fa5db0cb800
sub:  0x7fa5dabe5500

可以看到,子进程的变量首地址并没有按照我们预期的512字节对齐。