C语言 attribute

Attribute

参考文章

简介

目前市面上大多数的C/C++集成开发环境(IDE)使用的编译工具链主要是GCC、Clang、ARMCC、IAR Embedded Workbench。为了使用一些高级编译器特性,我们需要了解一些编译器指令,比如GNU C的__attribute__,这种指令在uboot和Linux源代码中经常被使用。

in GNUC or Clang

__Attribute__是 GNU C 的一大特色,其可以向编译器声明以下属性:

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

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

Clang 也借用了GCC的__attribute__,并进行了扩展。

语法格式:__attribute__ ((attribute-list))attribute的前面和后面都有两个底线,后面紧跟着两对元括号, attribute-list是一个用逗号分隔开的属性清单。

**位置约束:**放于声明的尾部 “;” 之前。

函数属性(Function Attribute)

常用属性

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)); // 4
  printf("%d", sizeof(strpkd));  // 3
}

aligned

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

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

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

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

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

struct mystr
{
  int16_t a[3];
} __attribute__ ((aligned));

section

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

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

上述代码分别在编译后,数组和函数所在的段分别为indentext_function

段定义相关可以去看[链接文件的讲解](GCC 链接脚本.md)

unused

unused 告诉编译器,如果修饰的函数或变量在程序中没有使用,编译时不提出 unused 警告

  1. 未使用的函数参数

    void example_function(int used_param, int unused_param __attribute__((unused))) {
        // 仅使用 used_param
        printf("Used parameter: %d\n", used_param);
    }
    
  2. 未使用的变量

    int global_variable __attribute__((unused)); // 未使用全局变量
    
    void example_function() {
        int used_variable = 10;
        int unused_variable __attribute__((unused)) = 20;  // 未使用局部变量
    
        printf("Used variable: %d\n", used_variable);
    }
    
  3. 未使用的函数

    static void unused_function() __attribute__((unused)); // 只能在声明处加 unused
    
    static void unused_function() {
        // 函数体
    }
    
    int main() {
        // 未调用 unused_function
        return 0;
    }
    

used

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值