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手册,在我们需要使用到编译器一些高级特性的时候,可以在手册中查找。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值