gcc __attribute__
GNU C 的一大特色就是__attribute__ 机制。__attribute__ 可以设置函数属性(Function Attribute )、变量属性(Variable Attribute )和类型属性(Type Attribute )。
__attribute__ 书写特征是:__attribute__ 前后都有两个下划线,并切后面会紧跟一对原括弧,括弧里面是相应的__attribute__ 参数。
__attribute__ 语法格式为:__attribute__ ((attribute-list))
其位置约束为:放于声明的尾部“ ;” 之前。
关键字__attribute__ 也可以对结构体(struct )或共用体(union )进行属性设置。大致有六个参数值可以被设定,即:aligned, packed, transparent_union, unused, deprecated 和 may_alias 。
在使用__attribute__ 参数时,你也可以在参数的前后都加上“__” (两个下划线),例如,使用__aligned__而不是aligned ,这样,你就可以在相应的头文件里使用它而不用关心头文件里是否有重名的宏定义。
aligned (alignment)
该属性设定一个指定大小的对齐格式(以字节 为单位),例如:
struct S {
short b[3];
} __attribute__ ((aligned (8)));
typedef int int32_t __attribute__ ((aligned (8)));
该声明将强制编译器确保(尽它所能)变量类 型为struct S 或者int32_t 的变量在分配空间时采用8 字节对齐方式。
如上所述,你可以手动指定对齐的格式,同 样,你也可以使用默认的对齐方式。如果aligned 后面不紧跟一个指定的数字值,那么编译器将依据你的目标机器情况使用最大最有益的对齐方式。例如:
struct S {
short b[3];
} __attribute__ ((aligned));
这里,如果sizeof (short )的大小为2 (byte ),那么,S 的大小就为6 。取一个2 的次方值,使得该值大于等于6 ,则该值为8 ,所以编译器将设置S 类型的对齐方式为8 字节。
aligned 属性使被设置的对象占用更多的空间,相反的,使用packed 可以减小对象占用的空间。
需要注意的是,attribute 属性的效力与你的连接器也有关,如果你的连接器最大只支持16 字节对齐,那么你此时定义32 字节对齐也是无济于事的。
packed
使用该属性对struct 或者union 类型进行定义,设定其类型的每一个变量的内存约束。当用在enum 类型 定义时,暗示了应该使用最小完整的类型(it indicates that the smallest integral type should be used)。
下面的例子中,packed_struct 类型的变量数组中的值将会紧紧的靠在一起,但内部的成员变量s 不会被“pack” ,如果希望内部的成员变量也被packed 的话,unpacked-struct 也需要使用packed 进行相应的约束。
struct unpacked_struct
{
char c;
int i;
};
struct packed_struct
{
char c;
int i;
struct unpacked_struct s;
}__attribute__ ((__packed__));
在GCC下:struct my{ char ch; int a;}__attrubte__ ((packed)) sizeof(int)=4;sizeof(my)=5
下面的例子中使用__attribute__ 属性定义了一些结构体及其变量,并给出了输出结果和对结果的分析。
程序代 码为:
#include<stdio.h> struct p{
int a;
char b;
short c;
}__attribute__((aligned())) pp; struct m {
char a;
int b;
short c;
}__attribute__((aligned())) mm; struct o
{
int a;
char b;
short c;
} oo; struct x{
int a;
char b;
struct p px;
short c;
}__attribute__((aligned())) xx;
int main()
{
printf("sizeof(int)=%d,sizeof(short)=%d.sizeof(char)=%d\n",sizeof(int),sizeof(short),sizeof(char));
printf("pp=%d,mm=%d \n", sizeof(pp),sizeof(mm));
printf("oo=%d,xx=%d \n", sizeof(oo),sizeof(xx));
}
输出结 果:
sizeof(int)=4,sizeof(short)=2.sizeof(char)=1
pp=8,mm=12
oo=8,xx=24
分析:
sizeof(pp):
sizeof(a)+sizeof(b)+sizeof(c)=4+1+1=6<8 所以sizeof(pp)=8
sizeof(mm):
sizeof(a)+sizeof(b)+sizeof(c)=1+4+2=7
但是 a 后面需要用 3 个字节填充,但是 b 是 4 个字节,所以 a 占用 4 字节, b 占用 4 个字节,而 c 又要占用 4 个字节。所以 sizeof(mm)=12
sizeof(oo):
sizeof(a)+sizeof(b)+sizeof(c)=4+1+2=7
因为默 认是以4 字节对齐,所以sizeof(oo)=8
sizeof(xx):
sizeof(a)+ sizeof(b)=4+1=5
sizeof(pp)=8; 即xx 是采用8 字节对齐的,所以要在a ,b 后面添3 个空余字节,然后才能存储px ,
4+1+ (3 )+8+1=17
因为xx 采用的对齐是8 字节对齐,所以xx 的大小必定是8 的整数倍,即xx 的大小是一个比17 大又是8 的倍数的一个最小值,由此得到
17<24 ,所以sizeof(xx)=24
参考:http://www.cnblogs.com/astwish/p/3460618.html
constructor&destructor
很犀利的2个属性,用于修饰某个函数, 经过constructor属性修饰过的函数, 可以在main函数
运行前就可以先运行完毕, 同理destructor在进程exit之前执行。.h>.h>
#include
#include void __attribute__((constructor)) test1(void)
{
printf("hehe.\n");
} void __attribute__((destructor)) test2(void)
{
printf("haha.\n");
} int main(void)
{
}.h>.h>
root@localhost.localdomain # ./test
hehe.
haha.
http://www.cnblogs.com/respawn/archive/2012/07/09/2583651.html
http://www.cnblogs.com/longdouhzt/archive/2012/11/15/2771351.html
http://blog.aliyun.com/959
gcc __attribute__的更多相关文章
- gcc __attribute__关键字举例之visibility【转】
转自:https://blog.csdn.net/starstarstone/article/details/7493144?utm_source=tuicool&utm_medium=ref ...
- 链接加载文件gcc __attribute__ section
在阅读源代码的过程中,发现一个头文件有引用: /** The address of the first device table entry. */ extern device_t devices[] ...
- __attribute__中constructor和destructor
1.前言 最近看到一份代码,看到一个函数前面用__attribute__((destructor))修饰,当时感觉有点怪怪的,搜了整个程序,也没发现哪个地方调用这个函数.于是从字面意思猜想,该函数会在 ...
- [小技巧] gcc attribute error 属性小试
gcc __attribute__ 里有一个属性是 error 能够用于编译时报错. 參考: https://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Functio ...
- 对 cloudwu 简单的 cstring 进行简单解析
题外话 以前也用C写过字符串,主要应用的领域是,大字符串,文件读取方面.写的很粗暴,用的凑合着.那时候看见云风前辈的一个开源的 cstring 串. 当时简单观摩了一下,觉得挺好的.也没细看.过了较长 ...
- [Linux]非root的R环境被conda破坏后如何恢复?
记录说明 这篇文章本来是用来记录Linux非root环境下安装PMCMRplus包折腾过程,但后来试过了各种方法安装不上这个R包后,我换上了Miniconda来安装.经前人提醒,一开始安装Minico ...
- gcc/linux内核中likely、unlikely和__attribute__(section(""))属性
查看linux内核源码,你会发现有很多if (likely(""))...及if (unlikely(""))...语句,这些语句其实是编译器的一种优化方式,具 ...
- 有关gcc的扩展__attribute__((unused))
================================ Author: taoyuetao Email: tao_yuetao@yahoo.com.cn Blog: taoyuetao.cu ...
- GCC扩展 __attribute__ ((visibility("hidden")))
试想这样的情景,程序调用某函数A,A函数存在于两个动态链接库liba.so,libb.so中,并且程序执行需要链接这两个库,此时程序调用的A函数到底是来自于a还是b呢? 这取决于链接时的顺序,比如先链 ...
随机推荐
- 关于Unity5.5中2D动画的制作
1.首先要创建一个精灵 GameProject--2Dproject--Sprite 叫bird 2.给这个精灵附加纹理,并让它显示自己想让它显示的场景层中,一般它的静止纹理就是动画的第一张图片 3. ...
- 嵌入式驱动开发之采集方式bypass mode---bypass mode
http://baike.baidu.com/link?url=HifFTlNRROR24lW_gSdTiG-eXooi08O0Eeq1mU6Yy0I1LOMW4kdumv25BOQbohV_428M ...
- Elasticsearch JVM Heap Size大于32G,有什么影响?
0.引言 在规划ES部署的时候,会涉及到data node的分配堆内存大小,而Elasticsearch默认安装后设置的内存是1GB,对于任何一个业务部署来说,这个都太小了. 设置Heap Size的 ...
- Oracle Data Provider for .NET的使用(三)-ORACLE与.NET类型对应关系
想来这个是最重要的事情了,因为多数情况下,我们使用dbhelper来调用数据库的时候,是因为如下三个地方导致错误: 1.错误的sql语句:末尾多了分号,少了部分关键字 2.sql中的参数与parame ...
- 设置两个WdatePicker的开始时间小于结束时间,结束时间大于开始时间
contract_start_date_id为开始时间ID contract_end_date_id为结束时间ID $("#contract_start_date_id").bin ...
- 微擎app端上传图片后删除不了图片
相信在微擎开发的哥们都知道, 微擎在手册方面还是有点坑的,根本不让人活啊.没办法, 开发时, 只能自己看着源码来搞>>>> 好, 不多说了. 现在来看一个坑 ..直接上代码\ ...
- Linux 文件夹含义(转)
1./bin :获得最小的系统可操作性所需要的命令 2./boot :内核和加载内核所需的文件 3./dev :终端.磁盘.调制解调器等的设备项 4./etc :关键的启动文件和配置文件 5./hom ...
- switch语句相关
Cannot switch on a value of type long. Only convertible int values, strings or enum variables are pe ...
- std::unique_lock
/*与Mutex RAII相关,方便线程上锁,相比std::lock_guard提供了更好的上锁解锁控制,反正我是没看出来也是在构造时上锁,在析构时解锁,感觉和lock_gurad大差不差都是在线程函 ...
- ListView.setDivider,自定义的Devider
ListView lv = getListView(); ColorDrawable sage = new ColorDrawable(this.getResources().getColor(R.c ...