GCC编译器函数属性声明__attribute__((attribute-list))

函数属性声明在GCC和C++中用于指定函数的特定行为,如优化调用或确保代码正确性。__attribute__((attribute_list))关键字用于声明函数属性,如noreturn、const和format。constructor属性使函数在程序启动前执行,而destructor属性则在程序结束时执行。如果在函数声明和定义处都添加属性,它们的效果会叠加,即使存在冲突的属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是函数属性声明?

 在 GNU C 和 C++ 中,您可以使用函数属性来指定某些函数属性,这些属性可能有助于编译器优化调用或更仔细地检查代码的正确性。例如,您可以使用属性来指定函数从不返回 (noreturn)、仅根据其参数的值返回一个值 (const),或者具有 printf 样式的参数 (format)。

使用函数属性声明时,需要用到关键字 __attribute__ ,它的格式如下:

__attribute__ ((list1, list2, ...., list-n))

 其中的list内容,可以在gcc.gnu.org官方网站上找到详细的描述,欢迎各位读者阅读我个人解析的list内容。

在书写时,请遵循以下的语法:

__attribute__((attribute_list)) int add(int a, int b); //OK

int __attribute__((attribute_list)) add(int a, int b); //OK

int add(int a, int b) __attribute__((attribute_list)); //OK

建议将所有的函数属性写到函数声明处,因为有些函数属性是不支持写到函数体处,例如weak属性,写到函数体处时将会引发编译错误。

如果在函数声明同时写出函数体时,注意__attribute__((attribute_list))就不能写到函数参数列表后面了:

__attribute__((attribute_list)) int sub(int a, int b){
    return a - b;
} //OK

int __attribute__((attribute_list)) sub(int a, int b){
    return a - b;
} //OK

int sub(int a, int b)  __attribute__((attribute_list)){
    return a - b;
} //wrong

第三种写法在编译时会报错。

注意:在函数声明、函数实现两个地方任意一个地方写__attribute__((attribute_list))起到的作用是相同的,也就是说,代码片段:

__attribute__((attribute_list)) int add(int a, int b);

int add(int a, int b){
    return a + b;
}

和以下代码片段起到的作用是相同的:

int add(int a, int b);

__attribute__((attribute_list)) int add(int a, int b){
    return a + b;
}

现在请考虑一种情况,如果我在函数声明和定义处都加入了函数属性定义__attribute__((attribute_list)) 会发生什么?

现在,我们拿函数属性constructor和destructor做实验,在fun函数的声明处加入constructor声明,在fun函数的实现处加入destructor声明。

注:简单来说,constructor属性用于在程序启动前执行一次函数,destructor属性用于在程序结束时执行一次函数。

#include <stdio.h>

__attribute__((constructor)) void fun(void);

__attribute__((destructor)) void fun(void){
        printf("hello world\n");
        return;
}

int main(){
        printf("into main function\n");
        fun();
        printf("return from main function\n");
        return 0;
}

运行结果为

hello world
into main function
hello world
return from main function
hello world

可以看到,在main函数执行前后fun函数都被执行了,也就是两个属性都起作用了。

同时,如果一个函数有多个声明,多个声明中的函数属性也会叠加。

#include <stdio.h>

__attribute__((constructor)) void fun(void);

__attribute__((destructor)) void fun(void);

void fun(void){
        printf("hello world\n");
        return;
}

int main(){
        printf("into main function\n");
        fun();
        printf("return from main function\n");
        return 0;
}

运行结果和上方代码一致。

如果函数声明在实现后,该函数声明中的函数属性也会附加到函数上去。 

#include <stdio.h>

void fun(void){
        printf("hello world\n");
        return;
}

__attribute__((constructor)) void fun(void);

__attribute__((destructor)) void fun(void);

int main(){
        printf("into main function\n");
        fun();
        printf("return from main function\n");
        return 0;
}

 运行结果和上方代码一致。

constructor属性和destructor属性并不冲突,但如果是两个相互冲突的属性呢?还请读者自行尝试。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值