浅谈C语言对齐
2024-01-07 17:33:33
这一次要介绍的是一个gcc编译参数:
__attribute__((__aligned__(n)))
这里,我们将不讨论结构体内部的对齐问题。
我们将分为三个部分介绍这个编译参数——针对变量
、类型
和结构体
。
针对变量
首先我们看一个简单的例子:
#include <stdio.h>
int main(void)
{
int i __attribute__((__aligned__(64))) = 10;
printf("%lx %lu\n", (unsigned long)&i, sizeof(i));
return 0;
}
通过编译后,执行这个程序,结果如下:
7fffadbc43c0 4
可以看到,变量i的内存地址的后6位为0。而变量i占用的内存大小为4个字节。
这说明,对齐使得i的内存起始地址向64字节对齐了,但不影响其内存大小。
针对类型
何为针对类型呢?我们来看下面这个例子:
#include <stdio.h>
typedef int Int __attribute__((__aligned__(64)));
int main(void)
{
Int i = 10;
printf("%lx %lu\n", (unsigned long)&i, sizeof(i));
return 0;
}
编译后运行,发现与上例结果相似,变量i的起始地址为64字节对齐。
那么如果我们修改一下,变为如下代码呢?
#include <stdio.h>
typedef int Int __attribute__((__aligned__(64)));
int main(void)
{
Int i[2] = {1, 10};
printf("%lx %lu\n", (unsigned long)&i, sizeof(i));
return 0;
}
此时,编译代码就会报错,遇到类似如下报错提示:
错误:数组元素的对齐边界比元素大小还要大
这话什么意思呢?
简单来说,数组i的每个元素要向64字节对齐,而每个数组元素所占内存大小为4字节,那么就会发现,元素之间有空隙。这就是这个报错的意思,数组元素不连续了。
针对结构体
最后,我们来看看结构体的一些行为是怎样的。示例如下:
#include <stdio.h>
struct test {
long a;
long b;
long c;
long d;
long e;
long f;
long g;
long h;
long i;
} __attribute__((__aligned__(64)));
int main(void)
{
struct test t;
printf("%lx %lu\n", (unsigned long)&t, sizeof(t));
return 0;
}
编译代码,然后运行,结果如下:
7ffe525cce40 128
可以看到,结构体变量t内存起始地址依旧保持了64字节对齐,且结构体变量的大小也变为64字节的整数倍了。
此时假设我们将代码中t定义的语句改为:
struct test t[2];
依旧可以通过编译。
可见,空隙问题对于结构体是不存在影响的,因为编译器只需要调整结构体大小就可以将空隙自动填平了。
文章来源:https://blog.csdn.net/weixin_40960130/article/details/135378713
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!