__attribute__((packed))详解

弱符号是什么?

弱符号:
假设两独或零星独以上全局符号(函数或变量名)名字如出一辙,而里边之一申明也weak
symbol(弱符号),则这个全局符号不谋面掀起更定义错误。链接器会忽略弱符号,去用普通的大局符号来分析所有对那一个标记的援,但当普通的全局符号不可用时,链接器会利用弱符号。当有函数或变量名或受用户覆盖时,该函数或变量名好注解也一个弱符号。弱符号也叫做weak
alias(弱别名)。

转载:http://blog.sina.com.cn/s/blog\_7e719f0501012tkt.html

attribute((weak))的作用

动静是如此的,遭受一个高难的问题:我们不确定外部模块是否提供一个函数func,可是咱只好为此这函数,即好模块的代码必须用到func函数:

extern int func(void);
...................
int a = func();
if( a > .....)
{
    ..........
}
............

咱俩不晓得func函数是否被定义了;
即时会招2个结实:

1:外部有这么些函数func,并且EXPORT_SYMBOL(func),那么以本人自己之模块使用那些函数func,正确。

2:外部其实不设有是函数,那么我们以func,程序间接倒。

之所以是时段,__attribute__((weak)) 派上了用场。

每当投机之模块中定义:

int  __attribute__((weak))  func(......)
{
    return 0;
}

拿照模块的func转成弱符号类型,假诺遇强符号类型(即外表模块定义了func),那么我们当本模块执行的func将会是标模块定义之func。

若果外部模块没有概念,那么,将谋面调用这一个弱符号,也即是在地点定义的func,间接归了一个1(重回值视具体意况而定)

一定给多了一个默认函数。

原理:连接器发现以设有弱符号和强符号,有限选用强符号,即使发现无在强符号,只设有弱符号,则选取弱符号。如果还无有:静态链接,恭喜,编译时报错,动态链接:对不起,系统不能起动。

weak属性只碰面当静态库(.o .a )中生效,动态库(.so)中莫碰面立竿见影。

 

强符号和弱符号的例子

选举个例证:
strong.c //生成 libstrong.so

#include <stdio.h>
void real_func()
{
    printf("int real func\n");
}

weak.c //生成libweak.so

#include <stdio.h>
void real_func() __attribute__((weak));
void real_func()
{
    printf("fake func\n");
}

如果

gcc main.c -lstrong -lweak

那么输出结果”real func”。

main.c

#include <stdio.h>
extern void real_func();
void main()
{
        real_func();
}

如果

gcc main.c -lweak -lstrong

这输出结果吧”fake func”。

足见,对于动态库,weak属性毫无效用,且main中调用哪个real_manbetx手机网页版,func(),取决于顺序。

如果将strong.c 和 weak.c编译成.a或者.o

gcc main.c strong.o weak.o

或者

gcc main.c strong.o weak.o

这输出结果仍旧”real func”。

由此,如若当so中使用weak属性,那么其余不称预期的景,都是唯恐出现的。

1. __attribute__ ((packed))
的用意就是是告编译器裁撤结构在编译过程被的优化对旅,遵照实际占用字节数进行针对性同步,是GCC特有的语法。这些力量是与操作系统没关系,跟编译器有关,gcc编译器不是劳累凑模式的,我以windows下,用vc的编译器也不是密不可分的,用tc的编译器就是紧密的。例如:

在TC下:struct my{ char ch; int a;}
sizeof(int)=2;sizeof(my)=3;(紧凑形式)

以GCC下:struct my{ char ch; int a;}
sizeof(int)=4;sizeof(my)=8;(非紧凑情势)

在GCC下:struct my{ char ch; int
a;}__attrubte__ ((packed)) sizeof(int)=4;sizeof(my)=5

2. __attribute__重在字首如若由此来当函数或数额讲明中装置其性。给函数赋给属性的最首要目标在受编译器举办优化。函数讲明遭的__attribute__((noreturn)),就是报编译器这些函数不相会再次回到给调用者,以便编译器在优化时失去丢不必要之函数重临代码。

GNU
C的同颇特征就是是__attribute__机制。__attribute__得装函数属性(Function
Attribute)、变量属性(Variable Attribute)和类型属性(Type
Attribute)。

__attribute__修特征是:__attribute__上下都出零星独下划线,并且前面会紧跟一对括弧,括弧里面是呼应的__attribute__参数。

__attribute__语法格式为:

__attribute__ ((attribute-list))

其二职务约:放于表明的尾“;”往日。

函数属性(Function
Attribute):函数属性可以拉开发者把部分特点添加到函数表明遭,从而可以如果编译器在错误检查点的效能还强有力。__attribute__体制吗要命容易和非GNU应用程序做到兼容的功力。

GNU CC需要拔取–Wall编译器来击活该效用,这是决定警告信息之一个不行好之法门。

packed属性:使用该属性可以让变量或者结构体成员用最小的针对齐格局,即针对变量是一律字节约对同,对域(field)是位对旅。

若果您看罢GPSR协议在TinyOS中之实现,你得会小心到脚的话语:
typedef struct {
    double x;
    double y;
} __attribute__((packed)) position_t;

起来我们尚可以了然,不久是概念一个结构体嘛!不过看后的言语,你或就是会晤一头雾水了,’
__attribute__((packed))’是什么东西?有什么打算?一类此外问号就便会于君头里冒充出来。就算此针对领会整个程序尚未啊震慑,但自身无思念让这些问题直接发呆在自之心血里,负担最重。省得未来刻骨铭心本,而且说不定有雷同天可就此底上吗。搞领悟这一个题材吧!

GNU
C的一律好特征(却不吃新家所理解)就是__attribute__机制。__attribute__好安装函数属性(Function
Attribute)、变量属性(Variable Attribute)和项目属性(Type
Attribute)。
__attribute__语法格式为:
__attribute__ ((attribute-list))

夫岗位约为:放于讲明的尾部“;”从前。

packed是路属性(Type
Attribute)的一个参数,使用packed可以抽对象占的长空。需要留意的是,attribute属性的听从和公的连接器也有关,假使您的连接器最充足就辅助16字节本着合,那么您这概念32字节对同为是行不通的。

采用该属性对struct或者union类型举办定义,设定其项目标诸一个变量的内存约束。当用在enum类型定义时,暗示了应有使最小完整的门类(it
indicates that the smallest integral type should be used)。

下的事例中,my-packed-struct类型的变量数组中的值会紧凑在一起,但中间的积极分子变量s不会面为“pack”,即便愿意中的成员变量也吃packed的话语,my-unpacked-struct也用用packed举办相应的羁绊。
struct my_unpacked_struct
{
     char c;
     int i;
};
         
struct my_packed_struct
{
     char c;
     int i;
     struct my_unpacked_struct s;
}__attribute__ ((__packed__));

 

 

于每个系统上看下者结构体的长吧。
    内存对一起,往往是出于编译器来做的,假如您以的是gcc,可以于概念变量时,添加__attribute__,来支配是否利用内存对旅,或是内存对旅到几独字节,以地方的结构体为条例:
 1)到4字节,同样可指定对一头到8字节。
struct student
{
    char name[7];
    uint32_t id;
    char subject[5];
} __attribute__
((aligned(4))); 

2)不对准伙同,结构体的长短,就是逐一变量长度的与
struct student
{
    char name[7];
    uint32_t id;
    char subject[5];
} __attribute__ ((packed));

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图