了解甚少的GNU C的__attribute__ 机制

摘要:
我最近遇到了一个问题,如果这里出现了与机制有关的问题,我们应该做一个很好的总结,以避免将来犯类似的错误。事实上,GNUC的一个特点是__attribute__Mechanism__attibute__该机制也很容易与非GNU应用程序兼容。

平时忙着赶项目,很多东西都是不求甚解,当工作中遇到的一些比较刁钻的问题时,才发现自己和那些大牛的

差距---内功。熟练码农和码神的最大区别估计就是内功是否深厚了。在自我反思的过程中,也要逐渐的积累一些很

基本的知识,争取能烂熟于心,这样,才能做出高质量的产品。

最近遇到了一个__attribute__ 机制相关的问题,在这里栽了跟头,就要好好总结一下,免得在以后的岁月中,再

犯类似的错误。

其实,GNU C的一大特色就是__attribute__机制。这种机制在嵌入式系统中应用十分广泛,它的神奇作用就表现

在三个地方:

  设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。

我也就针对这三个属性做个总结吧。

  函数属性(Function Attribute)

  函数属性可以帮助开发者把一些特性添加到函数声明中,从而可以使编译器在错误检查方面的功能更强大。__attribute__

机制也很容易同非GNU应用程序做到兼容之功效。GNU CC需要使用 –Wall编译器来击活该功能,这是控制警告信息的一个很

好的方式。

  格式:__attribute__ format
该__attribute__属性可以给被声明的函数加上类似printf或者scanf的特征,它可以使编译器检查函数声明和函数实际调用参数之间

的格式化字符串是否匹配。该功能十分有用,尤其是处理一些很难发现的bug。

  example:

__attribute__((format(printf,m,n)))
__attribute__((format(scanf,m,n)))

m:第几个参数为格式化字符串(format string);
n:参数集合中的第一个,即参数“…”里的第一个参数在函数参数总数排在第几,注意,有时函数参数里还有“隐身”的呢,后面会提到;

  源码实例参考:http://www.keil.com/support/man/docs/armcc/armcc_sam1436458756975.htm

         http://unixwiz.net/techtips/gnu-c-attributes.html

  变量属性(Variable Attribute)

  编译器的关键字__attribute__用来指定变量或结构位域的特殊属性。关键字后双括弧中的内容是属性说明。常用的关键字都有

哪些呢?

section("section-name")

packed

aligned(alignment)

举个例子:

在操作系统中常用的__attribute__ ((section("name"))) .....

就是通过着来实现的,这个的作用主要是:

编译生成的object file,代码会保存在".text"段,全局变量和静态变量会放在".data"和".bss"(未初始化的全局变量和局部静态变量)

利用GCC的扩展机制就可以做到自定义段了.

关于变量的还有其他例子,写的比较详细,需要可以参考:

http://www.cnblogs.com/respawn/archive/2012/07/09/2582078.html

http://www.cnblogs.com/astwish/p/3460618.html

类型属性(Type Attribute)

类型属性主要用在结构体的操作上,其实很多时候和变量属性结合使用的,下面的实例可以很好说明类型属性 的作用和使用方法:

   代码:

structp
{
inta;
charb;
shortc;
}__attribute__((aligned(4))) pp;
structm
{
chara;
intb;
shortc;
}__attribute__((aligned(4))) mm;
structo
{
inta;
charb;
shortc;
}oo;
structx
{
inta;
charb;
structp px;
shortc;
}__attribute__((aligned(8))) xx;
intmain()
{
printf("sizeof(int)=%d,sizeof(short)=%d.sizeof(char)=%d
",sizeof(int),sizeof(short),sizeof(char));
printf("pp=%d,mm=%d 
", sizeof(pp),sizeof(mm));
printf("oo=%d,xx=%d 
", sizeof(oo),sizeof(xx));
return 0;
}

输出结果:

sizeof(int)=4,sizeof(short)=2.sizeof(char)=1
pp=8,mm=12
oo=8,xx=24

免责声明:文章转载自《了解甚少的GNU C的__attribute__ 机制》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇liunx 之 redHat 下 java 环境的配置和安装8-26 Hystrix环境集成下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

IOS学习4——block代码块

本文转载自:iOS开发-由浅至深学习block 一、关于block 在iOS 4.0之后,block横空出世,它本身封装了一段代码并将这段代码当做变量,通过block()的方式进行回调。这不免让我们想到在C函数中,我们可以定义一个指向函数的指针并且调用: 1 bool executeSomeTask(void) { 2 //do somethin...

Linux设置和查看环境变量的方法

1. 显示环境变量HOME $ echo $HOME /home/redbooks 2. 设置一个新的环境变量hello $ export HELLO="Hello!" $ echo $HELLO Hello! 3. 使用env命令显示所有的环境变量 $ env HOSTNAME=redbooks.safe.org PVM_RS...

JAVA基础-栈与堆,static、final修饰符、内部类和Java内存分配

Java栈与堆 堆:顺序随意 栈:后进先出(Last-in/First-Out). Java的堆是一个运行时数据区,类的对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为...

函数响应式编程(FRP)从入门到”放弃”——基础概念篇

前言 研究ReactiveCocoa一段时间了,是时候总结一下学到的一些知识了。 一.函数响应式编程 说道函数响应式编程,就不得不提到函数式编程,它们俩到底有什么关系呢?今天我们就详细的解析一下他们的关系。 现在有下面4个概念,需要我们理清一下它们之间的关系:面向对象编程 Object Oriented Programming响应式编程 Reactive...

变量的结构赋值

ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解耦; 1 数组的解耦赋值 以前,为变量赋值,只能直接指定值。 let a = 1; let b = 2; let c = 3; ES6允许写成下面这样。 let [a, b, c] = [1, 2, 3]; 上面代码表示,可以从数组中提取值,按照对应位置,对变量赋值。 这种写法属于...

JavaScript-Runoob:JavaScript 数据类型

ylbtech-JavaScript-Runoob:JavaScript 数据类型 1.返回顶部 1、 JavaScript 数据类型 值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。 引用数据类型:对象(Object)、数组(Array)、函数(Fu...