一、介绍
- GNU C 的一大特色就是__attribute__ 机制
- attribute 可以设置函数属性(Function Attribute )、变量属性(Variable Attribute )和类型属性(Type Attribute )。
- attribute 书写特征是:attribute 前后都有两个下划线,并切后面会紧跟一对原括弧,括弧里面是相应的__attribute__ 参数。
- attribute 语法格式为:attribute ((attribute-list))
- 关键字__attribute__ 也可以对结构体(struct )或共用体(union )进行属性设置。大致有六个参数值可以被设定,即:aligned, packed, transparent_union, unused, deprecated 和 may_alias 。
- 在使用__attribute__ 参数时,你也可以在参数的前后都加上“__” (两个下划线),例如,使用__aligned__而不是aligned ,这样,你就可以在相应的头文件里使用它而不用关心头文件里是否有重名的宏定义。
二、使用:弱引用
C语言强、弱符号,强、弱引用 在公司项目开发的过程中,为了实现多平台兼容,增加代码的通用性,一般都是面向对象的设计思路;如果我们需要新增一个函数getTime,但是又不想影响到其他平台的使用,这个时候就需要弱引用。 弱引用:有强引用优先编译强引用,没有则编译器弱引用函数,避免编译出错
__attribute__ ((weak)) int32_t getTime()
{
OSA_WARN(" is unsupported\n");
return -1;
}
三、使用:section
- 提到section,就得说RO RI ZI了,在ARM编译器编译之后,代码被划分为不同的段,RO
Section(ReadOnly)中存放代码段和常量,RW Section(ReadWrite)中存放可读写静态变量和全局变量,ZI Section(ZeroInit)是存放在RW段中初始化为0的变量 - attribute((section(“section_name”))),其作用是将作用的函数或数据放入指定名为"section_name"对应的段中。
- 编译时为变量指定段名
const int descriptor[3] __attribute__ ((section ("descr"))) = { 1,2,3 };
long long rw[10] __attribute__ ((section ("RW")));
void Function_Attributes_section_0 (void) __attribute__ ((section ("new_section")));
void Function_Attributes_section_0 (void)
{
static int aStatic =0;
aStatic++;
}
__attribute__ ((section ("bar"))) int f3()
{
return 1;
}
四、使用:aligned 对齐
定对象的对齐格式(以字节为单位),如:
struct p
{
int a;
char b;
short c;
}__attribute__((aligned(4))) pp;
struct x
{
int a;
char b;
struct p px;
short c;
}__attribute__((aligned(8))) xx;
按照8字节对齐,sizeof(xx)=24
attrubte ((packed))
紧凑型,不进行对齐,变量多大就占用多大内存
在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
五、使用:at
绝对定位,可以把变量或函数绝对定位到Flash中,或者定位到RAM。
定位到flash中,一般用于固化的信息,如出厂设置的参数,上位机配置的参数,ID卡的ID号,flash标记等等
const u16 gFlashDefValue[512] __attribute__((at(0x0800F000))) = {0x1111,0x1111,0x1111,0x0111,0x0111,0x0111};
const u16 gflashdata__attribute__((at(0x0800F000))) = 0xFFFF;
六、使用:attribute((deprecated))
- 如果被变量或者函数的声明使用deprecated属性进行描述,那么编译器编译过程中不会产生警告或者错误,但是,被该属性描述的变量或者函数在其他地方被调用,那么编译会产生警告,警告信息中包含过时接口定义的位置及代码中的引用位置。
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#ifdef __GNUC__
# define GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y))
#else
# define GCC_VERSION_AT_LEAST(x,y) 0
#endif
#if GCC_VERSION_AT_LEAST(3,1)
# define attribute_deprecated __attribute__((deprecated))
#elif defined(_MSC_VER)
# define attribute_deprecated __declspec(deprecated)
#else
# define attribute_deprecated
#endif
#define FF_DISABLE_DEPRECATION_WARNINGS __pragma(warning(push)) __pragma(warning(disable:4996))
#define FF_ENABLE_DEPRECATION_WARNINGS __pragma(warning(pop))
attribute_deprecated
int variable_old = 0;
attribute_deprecated
void function_old(void);
void function_old(void)
{
printf("old function.\n");
return;
}
int _tmain(int argc, _TCHAR* argv[])
{
FF_DISABLE_DEPRECATION_WARNINGS
variable_old++;
FF_ENABLE_DEPRECATION_WARNINGS
function_old();
printf("hello world!\n");
system("PAUSE");
return 0;
}
编译报错:
1>------ 已启动生成: 项目: attribute_deprecated, 配置: Debug Win32 ------
1> attribute_deprecated.cpp
1>e:\testcode\attribute_deprecated\attribute_deprecated\attribute_deprecated.cpp(46): error C4996: 'function_old': 被声明为已否决
1> e:\testcode\attribute_deprecated\attribute_deprecated\attribute_deprecated.cpp(32) : 参见“function_old”的声明
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
|