2390|2

227

帖子

0

TA的资源

一粒金砂(高级)

楼主
 

来了解一下GNU C __attribute__机制 [复制链接]

介绍

 

目前市面上多数的C/C++ IDE使用的编译工具链都是GCC或者LLVM,包括很多的商业IDE的工具链也是基于优化过的GCC或LLVM。而在用到一些高级编译器特性时,我们需要去了解一些编译器命令,比如GNU C的__attribute__,在uboot和Linux源码中会常用到此命令。

__attribute__实际上是GCC的一种编译器命令,用来指示编译器执行实现某些高级操作。__attribute__可以设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。LLVM也借用了GCC的__attribute__,并进行了扩展。

函数属性可以帮助开发人员向函数声明中添加一些特性,这可以使编译器在错误检查方面增强。变量属性允许对变量或结构体成员使用特定的属性进行修饰,比如结构体的对齐控制。

__attribute__的语法格式

__attribute__ ((attribute-list))

attribute的前面和后面都有两个下划线,后面紧跟两对元括弧, attribute-list是一个用逗号分隔开的属性列表。__attribute__ ((attribute-list))放于声明的尾部“;”之前。

常用属性

1、packed

让编译器在编译时取消结构体的字节优化对齐,按照实际占用的字节数进行对齐。在某些场景用户不希望编译器对字节对齐进行调整,否则处理起来会比较麻烦,那么可以使用该属性。

例如在源码中定义了两个结构

struct unpacked_str

{

    uint8_t  x;

    uint16_t y;

};

 

struct packed_str

{

    uint8_t  x;

    uint16_t y;

}__attribute__ ((packed));

 

struct unpacked_str strupkd;

struct packed_str   strpkd;

 

int main(void)

{

    printf("%d", sizeof(strupkd));

    printf("%d", sizeof(strpkd));

}

使用clang编译,运行时分别输出为4和3。

2、aligned

规定变量或结构体成员最小对齐格式,以字节为单位。让用户自行决定变量的对齐字节数,比如一些处理器架构要求向量表需要按照规定的对齐地址放置,这时用户就需要进行控制了。

在代码中定义了一个32位变量:

uint32_t var_in_8bytes __attribute__((aligned(8)));

查看链接后的map映射文件,可以验证对齐的字节数和地址。

同样,你也可以使用默认的对齐方式。如果aligned后面不紧跟一个指定的数字值,那么编译器将依据你的目标机器情况使用最大最有益的对齐方式。

struct mystr

{

int16_t a[3];

} __attribute__ ((aligned));

3、section

section控制变量或函数在编译时的段名。在嵌入式软件开发时用的非常多,比如有外扩Flash或RAM时,需要将变量或函数放置到外扩存储空间,可以在链接脚本中指定段名来操作。在使用MPU(存储保护)的MCU编程时,需要对存储器划分区域,将变量或代码放置到对应的区域,通常也是通过段操作来实现。

const int identifier[3] __attribute__ ((section ("ident"))) = { 1,2,3 };

void myfunction (void) __attribute__ ((section ("ext_function")))

上述代码分别在编译后,数组和函数所在的段分别为“indent”和“ext_function”。

4、unused

意味着函数或变量很可能未被使用,编译器不会针对这个函数产生警告,可以将其声明在在函数实现中没有使用过的参数上,例如:

int main(int argc __attribute__((unused)), char **argv)

{ ...}

5、used

此属性附加到具有静态存储的变量,意味着即使该变量看起来没有被引用,也必须保留该变量。否则在链接的时候链接器发现某个变量未被引用,会将此变量优化掉。

6、weak

若两个或两个以上全局符号名字一样,而其中之一声明为weak symbol(弱符号),则这些全局符号不会引发重定义错误。当普通符号存在时,链接器会忽略掉弱符号,如果不存在普通符号,则使用弱符号。

 

更多的__attribute__属性可以参考GCC手册,在我们需要使用到编译器一些高级特性的时候,可以在手册中查找。

最新回复

这几个都经常用,确实GCC在这方面很方便。 去年想在vc下面做一个程序,想用类似gcc的section这样功能来实现某个功能,结果VC的编译器和连接器我死活找不到这样的东西。我安慰自己PE应该比ELF高级吧,所以不需要。   详情 回复 发表于 2022-3-8 23:06
点赞 关注
个人签名

欢迎关注“麦克泰技术”


回复
举报

1万

帖子

25

TA的资源

版主

沙发
 

这个值得收藏

 
 

回复

7452

帖子

2

TA的资源

五彩晶圆(高级)

板凳
 

这几个都经常用,确实GCC在这方面很方便。

去年想在vc下面做一个程序,想用类似gcc的section这样功能来实现某个功能,结果VC的编译器和连接器我死活找不到这样的东西。我安慰自己PE应该比ELF高级吧,所以不需要。

 
个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表