__attribute__((aligned(n)))和__attribute__((packed))

2023-10-27

__attribute__GUN C中极具特设的一大机制,可以用来设置

  • 函数属性(Function Attribute)
  • 变量属性(Variable Attribute)
  • 类型属性(Type Attribute)

这里我们主要阐述用__attribute__((aligned(n)))__attribute__((packed))两个指令对结构体进行属性设置

一、作用简述

__attribute__((aligned(n)))   //采用n字节对齐
__attribute__((packed))       //采用1字节对齐

其中

  • __attribute__((aligned(n)))中,n的有效参数为2的幂值,32位最大为2 ^ 32,64位为2 ^ 64,这个时候编译器会将n与默认的对齐字节数进行比较取较大值为对齐字节数,与#pragma pack(n)恰好相反。
  • __attribute__((packed))则为取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐,也就是采用1字节对齐。

二、在结构体类型中的使用方法

2.1 使用格式

/*定义结构体时不对类型重命名*/
struct mystruct
{
    /*成员变量定义*/
}__attribute__() /*(可同时在这定义变量)*/;

struct __attribute__() mystruct
{
    /*成员变量定义*/
}/*(可同时在这定义变量)*/;

/*定义结构体同时对类型进行重命名*/
typedef struct mystruct
{
    /*成员变量定义*/
}__attribute__() MS;

typedef struct __attribute__() mystruct
{
    /*成员变量定义*/
}MS;

2.2 测试代码

#include <stdio.h>

typedef struct mystruct1
{            //in64_64     in32_32
    int a;   //(4 + 4)        4
    double b;// 8             8
    char c;  //(1 + 15)     (1 + 3)
}__attribute__((aligned(16))) AMS1;//in 64_64:32; in 32_32:16


typedef struct __attribute__((aligned(16))) mystruct2
{            //in64_64     in32_32
    int a;   //(4 + 4)        4
    double b;// 8             8
    char c;  //(1 + 15)     (1 + 3)
}AMS2;      //in 64_64:32; in 32_32:16

struct mystruct3
{
    int a;
    double b;
    char c;
}__attribute__((aligned(16))) test3;

struct __attribute__((aligned(16))) mystruct4
{
    int a;
    double b;
    char c;
}test4;

typedef struct mystruct5
{
    int a;   //4
    double b;//8
    char c;  //1
}__attribute__((packed)) PMS5;//in 64_64:13; in 32_32:13

typedef struct mystruct6
{            //in64_64     in32_32
    int a;   //(4 + 4)        4
    double b;// 8             8
    char c;  //(1 + 7)     (1 + 3)
}__attribute__((aligned(8))) A8MS6;//in 64_64:24; in 32_32:16

typedef struct mystruct7
{            //in64_64     in32_32
    int a;   //(4 + 4)        4
    double b;// 8             8
    char c;  //(1 + 7)     (1 + 3)
}__attribute__((aligned(2))) A2MS7;//in 64_64:24; in 32_32:16

typedef struct mystruct8
{            //in64_64      in32_32
    int a;   //(4 + 4)        4
    double b;// 8             8
    char c;  //(1 + 15)     (1 + 19)
}__attribute__((aligned(32))) A32MS8;//in 64_64:32; in 32_32:32


int main(void)
{
    AMS1 test1;
    AMS2 test2;
    printf("sizeof(test1)    = %d\n", (int)sizeof(test1));
    printf("sizeof(test2)    = %d\n", (int)sizeof(test2));
    printf("sizeof(test3)    = %d\n", (int)sizeof(test3));
    printf("sizeof(test4)    = %d\n", (int)sizeof(test4));
    printf("sizeof(PMS5)     = %d\n", (int)sizeof(PMS5));
    printf("sizeof(A8MS6)    = %d\n", (int)sizeof(A8MS6));
    printf("sizeof(A2MS7)    = %d\n", (int)sizeof(A2MS7));
    printf("sizeof(A32MS8)   = %d\n", (int)sizeof(A32MS8));
    return 0;
}

2.3 测试结果

在这里插入图片描述
其中,test1~test4主要进行格式的测试。对于__attribute__((aligned(16))),对齐图示如下(文字描述参照代码中的注释):
在这里插入图片描述
对于其他的n也是这样分析:

  • 在64位操作系统64位编译器的环境下,当n ≥ 8时,内存对齐的字节数是n,不然为8
  • 在32位操作系统32位编译器的环境下,当n ≥ 4时,内存对齐的字节数是n,不然为4

PMS5也可以看出,__attribute__((packed))就是一字节对齐

三、aligned(n)在变量、函数中的使用

3.1 在变量中的使用

C/C++中长度为n字节的基本数据类型的变量在编译时会被编译器默认分配到n字节对齐的内存上。例如,int的长度是4字节,所以int类型变量将被分配到4字节对齐的地址上。我们也可以通过__attribute__((aligned(n)))来改变这种默认状态。

int a __attribute__ ((aligned (16))) = 0;

这样就把a分配到了16字节对齐的地址上。

3.2在函数中的使用

和改变变量的默认对齐状态一样,也可以通过__attribute__((aligned(n)))来改变函数的自然对齐状态。

void __attribute__ ((aligned (64))) func(void)
{
    /*功能实现代码*/
}

关于__attribute__这里只浅显地总结这么一点东西,如果需要更加丰富的内容,请查阅:
GCC手册:使用GUN编译器集合(GCC)类型属性

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

__attribute__((aligned(n)))和__attribute__((packed)) 的相关文章

  • C++:头文件中全局函数的多重定义错误

    该函数是全局的 在头文件中定义 暂时地我想把它留在那里 头文件还构成一个具有内联函数的特定类 其中一个函数调用this全局函数 源文件不包含任何有问题的全局函数 有关错误原因的任何提示吗 如果有人感兴趣的话我可以发布代码 mainwindo
  • 在两个 .cpp 文件之间定义全局变量 [重复]

    这个问题在这里已经有答案了 如何在 A cpp 和 B cpp 之间共享 全球化 bool 变量 其中它们都不包含其他 h 文件 他们有其他联合头文件 但彼此没有 我可以在这些共享标头中定义全局变量吗 Thanks 我可以在这些共享标头中定
  • .NET Windows 服务中调用 C# 的 wait 的 I/O 回调是否可以不阻塞?

    我知道在 ASP NET 中 当使用 wait 时工作线程会返回到池中 而 I O 发生在后台 这对于可扩展性非常有用 我的 Windows 服务是一个套接字服务器 它使用 Begin End 样式的异步套接字 I O 混合我的魔法 我知道
  • C/C++ 中随机数生成器的实现[重复]

    这个问题在这里已经有答案了 我对 C 中随机数生成器的实现有点困惑 它也与 C 中的明显不同 如果我理解正确 对 srand seed 的调用会以某种方式初始化可通过 rand 访问的隐藏变量 种子 该变量又将函数指向预先生成的序列 例如例
  • WPF - 按多列排序时使用自定义比较器

    我有一个 ListView GridView 我想按 2 列排序 因此如果第 1 列中有 2 个以上的项目具有相同的值 它将按第 2 列排序 非常简单 但是在对 A Z 进行排序时 空字符串会出现在顶部 我想把它们移到底部 我制作了一个比较
  • 如何检查 .NET 4.0 中的泛型参数是否是动态的

    我有课ObjectMapper
  • 当我尝试使用 AVX 功能时,Clang 生成错误

    我使用的是 Windows 10 使用 Clang 版本 5 最近安装 当我编译以下内容时 define AVX define AVX2 include
  • Windows 程序如何临时更改其时区?

    我写了一个函数来返回time t与给定日期的午夜相对应的值 当给定日期没有午夜时 它返回最早可用的时间 例如 当埃及进入夏令时时 这种情况就可能发生 今年 时间更改于 4 月 29 日晚上午夜生效 因此时钟直接从 23 59 转到 01 0
  • 首先EntityFramework数据库 - 类型映射 - 将binary(8)从SQL映射到C#中的int

    在 SQL 内部 我有一个主键为二进制 8 的表 当我使用该表添加到我的模型中时Update Model from Database我可以看到该列有 type Binary 在 C 中 我将该列设为byte 我可以将该列映射到 int 吗
  • 使用 Microsoft Graph 创建用户

    如何使用 Microsoft graph 创建用户 因为我在保存过程中遇到了权限失败的问题 我确实有几个问题 在图中调用创建用户 API 将在哪里创建用户 是在 Azure AD 还是其他地方 我尝试通过传递 json 和必需的标头来调用创
  • C++ 析构函数:何时释放内存?

    如果我删除一个导致其析构函数被调用的对象 那么内存是在析构函数完成函数中的任何操作之前还是之后被释放 仅当最小派生类子对象被销毁后才会释放内存 所以如果你有 class Base class Derived public Base publ
  • 从 ef core 的子集合中删除一些项目

    我有一个父表和子表 其中父表与子表具有一对多关系 我想删除一些子项 并且希望父项的子集合反映该更改 如果我使用删除选定的子项RemoveRange 那么子集合不会更新 如果我使用Remove从子集合中删除子集合然后 显然 它不如使用效率高R
  • 基于 C++ 范围的 for 循环

    尝试使用基于范围的 for 循环执行某些操作 可以使用常规的 for 循环来完成 如下所示 vector
  • 在非指针变量和类成员上放置 new

    考虑以下示例 include
  • 打破条件变量死锁

    我遇到这样的情况 线程 1 正在等待条件变量 A 该变量应该由线程 2 唤醒 现在线程 2 正在等待条件变量 B 该变量应该由线程 1 唤醒 在我使用的场景中条件变量 我无法避免这样的死锁情况 我检测到循环 死锁 并终止死锁参与者的线程之一
  • IEnumerable.比带中断的 for 循环更快吗?

    我们的代码打开表单时遇到了一些缓慢的情况 这可能是由于for循环与break这需要很长时间才能执行 我把它切换到IEnumerable Any 并看到表格很快打开 我现在试图弄清楚是否单独进行此更改会提高性能 或者是否正在访问Product
  • 语义问题 Qt Creator:命名空间“std”中没有名为“cout”的成员

    我开始使用 Qt Creator 编写代码 对于 C 文件 我遇到很多语义问题 99 是 命名空间 yyy 中没有名为 xxx 的成员cpp文件构建 编译和输出没有问题 如果我点击例如cout 我已链接到 iostream 我是否需要在 Q
  • C# - 命名空间内的类型声明

    在命名空间内而不是在类中声明类型的可能用途是什么 For ex namespace Test public delegate void Ispossible 这是有效的并且不会产生任何编译错误 但我无法想象为什么我们会以这种方式声明它而不是
  • printf 参数不足

    我的问题是关于缺少参数的 printf 之后的行为 printf s blah blah d int integer was given as argument and not int written 我已经知道 如果格式参数不足 则行为是
  • 请解释为什么Java和C对此代码给出不同的答案

    public class Test public static void main String args int i 10 i i System out println value of i is i 输出是 10 当我在中执行类似的代码

随机推荐

  • 菜鸟入门Docker

    菜鸟入门Docker 说明 一 什么是Docker 1 虚拟机和Linux容器 二 Docker用途 三 Docker安装 1 设置仓库 2 安装 Docker Engine Community 3 验证安装成功 四 Docker启动与停止
  • Linux必杀(十八):VI、VIM编辑器

    题记 基本上VI共分为3种模式 分别是一般模式 命令行模式和编辑模式 一 一般模式 以Vi打开一个文件就直接进入一般模式了 在这个模式下 可以使用上下左右按键来移动光标 可以删除字符或删除整行 也可以复制 粘贴文件数据 二 编辑模式 在一般
  • Dubbo中的一些常见问题?

    关于dubbo是用的什么协议 在使用dubbo的时候会配置
  • ubuntu 防火墙基本设置

    查看防火墙状态 ufw status 打开防火墙 sudo ufw enable 重启防火墙 sudo ufw reload 开放指定端口 ufw allow 8080
  • 使用C语言打印不同星号图案(矩形 平行四边形 三角形)

    献给大一或大二的学弟学妹们和在自学 C语言的同志们 打印自定义行数的矩形 打印效果 参考代码 include
  • echarts 图表无数据为空时显示“暂无数据”

    如标题所述 我们希望 echarts 图表在没有数据时显示 暂无相关数据 字样 操作 需要对返回的数据做判断 如果有数据则正常显示图表 如果没有数据 我们将此 div 的内容改为文本 暂无相关数据 并设置样式即可 HTML div div
  • 从感知机到Transformer,一文概述深度学习简史

    关注公众号 发现CV技术之美 本文转自机器之心 作者 Jean de Dieu Nyandwi 机器之心编译 这篇文章从感知机开始 按照时间顺序回顾了深度学习的历史 1958 年 感知机的兴起 1958 年 弗兰克 罗森布拉特发明了感知机
  • Java中的异常

    Java中的异常 1 什么是异常 2 异常的类结构 3 运行时异常的特点 4 编译时异常特点 5 对受检异常进行处理 5 1 try catch 捕获处理 5 2 finally子句处理 5 3 finally子句 5 4 throws抛出
  • java案例之制作系统

    java案例之制作系统 案例 需求 定义一个方法 可以接收中奖号码的数组 用户选号的数组 根据命中红球数和篮球数判断最终的结果并输出 分析 系统需要三部份 第一部分是 生成随机产生的7位数双色球数字 其中前6位是红球 第7位是蓝球 红球范围
  • 使用MySQL Workbench建立数据库,建立新的表,向表中添加数据

    点击上图中的 加号 图标 新建一个连接 如上图 先输入数据库的账号密码 帐号默认为root 填好密码后 点击 OK 连接就建立好了 建立完成后 会出现一个长方形的框框 双击它 出现下图所示页面 点击图中的红圈里的按钮 新建一个Schema
  • 图的深度优先遍历(递归与非递归算法)和广度优先遍历

    老师的题目 实验内容 已知某地区的公路网以图表示 图中的顶点表示站点 任意两站点间的路段以带权的边构成的邻接矩阵表示 矩阵中非零元表示两个站点间存在直接的路段 否则没有路段 打开E Test文件夹中的exp06 cpp文件 补充编写所需代码
  • html做成小程序,微信小程序——简单静态网页的制作

    一 前言 需要知识 HTML CSS 注意 微信小程序的语法与HTML和CSS不太相同 但本质是一样的 要求 进入开发者工具并且创建一个测试小程序 选择建立快速模板 在pages目录底下新建一个first的文件夹 其中包括指定的四个文件 并
  • react 组件逻辑复用

    组件逻辑复用 React为什么设计成组件化的形式 其实最大的原因就是为了方便复用 然而组件的复用虽然方便 逻辑的复用却很麻烦 因为state的存在 逻辑被锁死在组件内部 很难分离出去 下面以一个可以改变背景色的步进器为例 展示react中常
  • 复制PDF文字时去掉换行符

    问题描述 当我们在pdf上复制文字时 每行总会出现换行符 乱糟糟的 解决方法 注意 windows推荐开源软件cpoy gihub copy 临时使用 推荐网页 文字替换在线处理工具 在快捷指令中新建 快捷服务 选择执行shell脚本 写这
  • 苹果开发者ADP协议第3.2(f)节违反

    相信很多开发者都遇到过 ADP协议第3 2 f 节违反 导致账号被封 遇到这种情况基本没戏 不用再联系苹果了 基本没戏 以下是被封的邮件信息 Hello xxx This letter serves as notice of termina
  • DSP CCS 12.00运用, 产生正弦波的图像 芯片:F28335

    1 首先建立新的项目 工程 2 参数选择 3 设置数据 保证与芯片得连接 4 整理思路 信号频率 1000 HZ 采样频率 20000 HZ 采样点数 128 5 代码 头文件的定义 include stdio h include math
  • vue-aplayer在手机移动端的时候默认没有总时长,点击播放才显示总时长问题

    前言 在移动段使用vue aplayer这款音频播放组件的时候 发现他默认的时候看不到总时长 只有点击播放才能看到 我的数据是从后台直接拿来的 观察官网没有这个问题 既然出现问题就得解决问题 这里分享下我的解决办法 解决办法一 尝试过但是不
  • C语言中 char str[] 与 char *str 的关系

    首先 我们得明确 在C语言中 没有真正的字符串类型 所以 就诞生了 字符串数组 这么个类型 于是 当我们想申明一个字符串变量时 大体上有下面两种方法 char str hello char p hello str 它定义的是一个字符串数组变
  • golang-- 字典树

    一 前言 看了百度团队在 infoq 上发表的一篇 如何在秒级完成词表匹配 https xie infoq cn article 97b2df7e41456335627ce4cd4 的文章 文章业务背景介绍的很清楚 里面有提到字典树 看到结
  • __attribute__((aligned(n)))和__attribute__((packed))

    绪 attribute 是GUN C中极具特设的一大机制 可以用来设置 函数属性 Function Attribute 变量属性 Variable Attribute 类型属性 Type Attribute 这里我们主要阐述用 attrib