曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 5225|回复: 1
打印 上一主题 下一主题

GNU C 扩展之__attribute__ 机制简介

[复制链接]

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
跳转到指定楼层
楼主
发表于 2009-8-13 19:36:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
<span class="content"> <br />
</span>
<p style="text-indent: 21pt;" class="MsoNormal"><span lang="EN-US">GNU C</span><span style="font-family: 宋体;">的一大特色(却不被初学者所知)就是</span><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">机制。</span><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">可以设置函数属性(</span><span lang="EN-US">Function Attribute</span><span style="font-family: 宋体;">)、变量属性(</span><span lang="EN-US">Variable Attribute</span><span style="font-family: 宋体;">)和类型属性(</span><span lang="EN-US">Type Attribute</span><span style="font-family: 宋体;">)。</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">书写特征是:</span><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">前后都有两个下划线,并切后面会紧跟一对原括弧,括弧里面是相应的</span><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">参数。</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">语法格式为:</span><span lang="EN-US"><o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US">__attribute__ ((<span>attribute-list</span>))<o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">其位置约束为:</span><span lang="EN-US"><o:p /></span></p>

<p class="MsoNormal"><span style="font-family: 宋体;">放于声明的尾部“;”之前。</span><span lang="EN-US"><o:p /></span></p>

<h1><span style="font-size: 14pt;">函数属性(<span lang="EN-US">Function Attribute</span>)<span lang="EN-US"><o:p /></span></span></h1>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">函数属性可以帮助开发者把一些特性添加到函数声明中,从而可以使编译器在错误检查方面的功能更强大。</span><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">机制也很容易同非</span><span lang="EN-US">GNU</span><span style="font-family: 宋体;">应用程序做到兼容之功效。</span><span lang="EN-US"><o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US">GNU CC</span><span style="font-family: 宋体;">需要使用</span><span> <span lang="EN-US">–Wall</span></span><span style="font-family: 宋体;">编译器来击活该功能,这是控制警告信息的一个很好的方式。下面介绍几个常见的属性参数。</span><span lang="EN-US"><o:p /></span></p>

<h2><span lang="EN-US" style="font-size: 12pt; line-height: 173%; font-family: 'Times New Roman';">__attribute__ format<o:p /></span></h2>

<p style="text-indent: 21&#46;75pt;" class="MsoNormal"><span style="font-family: 宋体;">该</span><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">属性可以给被声明的函数加上类似</span><span lang="EN-US">printf</span><span style="font-family: 宋体;">或者</span><span lang="EN-US">scanf</span><span style="font-family: 宋体;">的特征,它可以使编译器检查函数声明和函数实际调用参数之间的格式化字符串是否匹配。该功能十分有用,尤其是处理一些很难发现的</span><span lang="EN-US">bug</span><span style="font-family: 宋体;">。</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21&#46;75pt;" class="MsoNormal"><span lang="EN-US">format</span><span style="font-family: 宋体;">的语法格式为:</span><span lang="EN-US"><o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">format (archetype, string-index, first-to-check)<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">       format</span><span style="font-family: 宋体;">属性告诉编译器,按照</span><span lang="EN-US">printf, scanf, strftime</span><span style="font-family: 宋体;">或</span><span lang="EN-US">strfmon</span><span style="font-family: 宋体;">的参数表格式规则对该函数的参数进行检查。</span><span style="font-family: 宋体;">“</span><span lang="EN-US">archetype</span><span style="font-family: 宋体;">”</span><span style="font-family: 宋体;">指定是哪种风格;</span><span style="font-family: 宋体;">“</span><span lang="EN-US">string-index</span><span style="font-family: 宋体;">”</span><span style="font-family: 宋体;">指定传入函数的第几个参数是格式化字符串;</span><span style="font-family: 宋体;">“</span><span lang="EN-US">first-to-check</span><span style="font-family: 宋体;">”</span><span style="font-family: 宋体;">指定从函数的第几个参数开始按上述规则进行检查。</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21&#46;75pt;" class="MsoNormal"><span style="font-family: 宋体;">具体使用格式如下:</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21&#46;75pt;" class="MsoNormal"><tt><span lang="EN-US" style="font-family: 'Times New Roman';">__attribute__((format(printf,<span>m</span>,<span>n</span>)))<o:p /></span></tt></p>

<p style="text-indent: 21&#46;75pt;" class="MsoNormal"><tt><span lang="EN-US" style="font-family: 'Times New Roman';">__attribute__((format(scanf,<span>m</span>,<span>n</span>)))<o:p /></span></tt></p>

<p style="text-indent: 21&#46;75pt;" class="MsoNormal"><span style="font-family: 宋体;">其中参数</span><span lang="EN-US">m</span><span style="font-family: 宋体;">与</span><span lang="EN-US">n</span><span style="font-family: 宋体;">的含义为:</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21&#46;75pt;" class="MsoNormal"><span lang="EN-US">m</span><span style="font-family: 宋体;">:第几个参数为格式化字符串(</span><span lang="EN-US">format string</span><span style="font-family: 宋体;">);</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21&#46;75pt;" class="MsoNormal"><span lang="EN-US">n</span><span style="font-family: 宋体;">:参数集合中的第一个,即参数“</span><span lang="EN-US">…</span><span style="font-family: 宋体;">”里的第一个参数在函数参数总数排在第几,注意,有时函数参数里还有“隐身”的呢,后面会提到;</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21&#46;75pt;" class="MsoNormal"><span style="font-family: 宋体;">在使用上,</span><tt><span lang="EN-US" style="font-family: 'Times New Roman';">__attribute__((format(printf,<span>m</span>,<span>n</span>)))</span></tt><tt><span>是常用的,而另一种却很少见到。下面举例说明,其中</span></tt><span lang="EN-US">myprint</span><span style="font-family: 宋体;">为自己定义的一个带有可变参数的函数,其功能类似于</span><span lang="EN-US">printf</span><tt><span>:</span></tt><tt><span lang="EN-US" style="font-family: 'Times New Roman';"><o:p /></span></tt></p>

<p style="text-indent: 21&#46;75pt;" class="MsoNormal"><tt><span lang="EN-US" style="font-family: 'Times New Roman';">//m=1</span></tt><tt><span>;</span></tt><tt><span lang="EN-US" style="font-family: 'Times New Roman';">n=2<o:p /></span></tt></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">extern void myprint(const char *format,&#46;&#46;&#46;) __attribute__((format(printf,1,2)));<o:p /></span></p>

<p style="text-indent: 21&#46;75pt;" class="MsoNormal"><tt><span lang="EN-US" style="font-family: 'Times New Roman';">//m=2</span></tt><tt><span>;</span></tt><tt><span lang="EN-US" style="font-family: 'Times New Roman';">n=3<o:p /></span></tt></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">extern void myprint(int l</span><span style="font-family: 宋体;">,</span><span lang="EN-US">const char *format,&#46;&#46;&#46;) __attribute__((format(printf,2,3)));<o:p /></span></p>

<p align="left" style="text-indent: 21pt; text-align: left;" class="MsoNormal"><span style="font-family: 宋体;">需要特别注意的是,如果</span><span lang="EN-US">myprint</span><span style="font-family: 宋体;">是一个函数的成员函数,那么</span><span lang="EN-US">m</span><span style="font-family: 宋体;">和</span><span lang="EN-US">n</span><span style="font-family: 宋体;">的值可有点“悬乎”了,例如:</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21&#46;75pt;" class="MsoNormal"><tt><span lang="EN-US" style="font-family: 'Times New Roman';">//m=3</span></tt><tt><span>;</span></tt><tt><span lang="EN-US" style="font-family: 'Times New Roman';">n=4<o:p /></span></tt></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">extern void myprint(int l</span><span style="font-family: 宋体;">,</span><span lang="EN-US">const char *format,&#46;&#46;&#46;) __attribute__((format(printf,3,4)));<o:p /></span></p>

<p align="left" style="text-indent: 21pt; text-align: left;" class="MsoNormal"><span style="font-family: 宋体;">其原因是,类成员函数的第一个参数实际上一个“隐身”的“</span><span lang="EN-US">this</span><span style="font-family: 宋体;">”指针。(有点</span><span lang="EN-US">C++</span><span style="font-family: 宋体;">基础的都知道点</span><span lang="EN-US">this</span><span style="font-family: 宋体;">指针,不知道你在这里还知道吗?)</span><span lang="EN-US"><o:p /></span></p>

<p align="left" style="text-indent: 21pt; text-align: left;" class="MsoNormal"><span style="font-family: 宋体;">这里给出测试用例:</span><span lang="EN-US">attribute&#46;c</span><span style="font-family: 宋体;">,代码如下:</span><span lang="EN-US"><o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">1</span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 宋体;">:</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">2</span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 宋体;">:</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">extern void myprint(const char *format,&#46;&#46;&#46;) __attribute__((format(printf,1,2)));<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">3</span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 宋体;">:</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">4</span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 宋体;">:</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">void test()<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">5</span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 宋体;">:</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">{<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">6</span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 宋体;">:</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><span> </span>myprint("i=%d\n",6);<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">7</span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 宋体;">:</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><span> </span>myprint("i=%s\n",6);<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">8</span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 宋体;">:</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><span> </span>myprint("i=%s\n","abc");<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">9</span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 宋体;">:</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><span> </span>myprint("%s,%d,%d\n",1,2);<o:p /></span></p>

<p class="MsoNormal"><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">10</span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 宋体;">:</span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">}<o:p /></span></p>

<p class="MsoNormal"><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><o:p> </o:p></span></p>

<p style="text-indent: 21&#46;75pt;" class="MsoNormal"><span style="font-family: 宋体;">运行</span><span lang="EN-US">$gcc –Wall –c </span><span lang="EN-US">attribute&#46;c attribute</span><span style="font-family: 宋体;">后,输出结果为:</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21&#46;75pt;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">attribute&#46;c: In function `test':<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">attribute&#46;c:7: warning: format argument is not a pointer (arg 2)<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">attribute&#46;c:9: warning: format argument is not a pointer (arg 2)<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">attribute&#46;c:9: warning: too few arguments for format</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">如果在</span><span lang="EN-US">attribute&#46;c</span><span style="font-family: 宋体;">中的函数声明去掉</span><span lang="EN-US">__attribute__((format(printf,1,2)))</span><span style="font-family: 宋体;">,再重新编译,既运行</span><span lang="EN-US">$gcc –Wall –c </span><span lang="EN-US">attribute&#46;c attribute</span><span style="font-family: 宋体;">后,则并不会输出任何警告信息。</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">注意,默认情况下,编译器是能识别类似</span><span lang="EN-US">printf</span><span style="font-family: 宋体;">的“标准”库函数。</span><span lang="EN-US"><o:p /></span></p>

<h2><span lang="EN-US" style="font-size: 12pt; line-height: 173%; font-family: 'Times New Roman';">__attribute__ noreturn<o:p /></span></h2>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">该属性通知编译器函数从不返回值,当遇到类似函数需要返回值而却不可能运行到返回值处就已经退出来的情况,该属性可以避免出现错误信息。</span><span lang="EN-US">C</span><span style="font-family: 宋体;">库函数中的</span><span lang="EN-US">abort</span><span style="font-family: 宋体;">()和</span><span lang="EN-US">exit</span><span style="font-family: 宋体;">()的声明格式就采用了这种格式,如下所示:</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<pre><span lang="EN-US" style="font-size: 10&#46;5pt; font-family: 'Times New Roman';">extern void exit(int)<span> </span><span>__attribute__((noreturn))</span><o:p /></span></pre>
<pre><span lang="EN-US" style="font-size: 10&#46;5pt; font-family: 'Times New Roman';">extern void abort(void) <span>__attribute__((noreturn))</span><o:p /></span></pre>
<pre><span lang="EN-US" style="font-size: 10&#46;5pt; font-family: 'Times New Roman';"><o:p> </o:p></span></pre>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">为了方便理解,大家可以参考如下的例子:</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">//name: </span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">noreturn&#46;c<span> </span></span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 宋体;">;测试</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">__attribute__((noreturn))</span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">extern void myexit();<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><o:p> </o:p></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">int test(int n)<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">{<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><span> </span>if ( n > 0 )<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><span> </span>{<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><span> </span>myexit();<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><span> </span>/* </span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 宋体;">程序不可能到达这里</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">*/<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><span> </span></span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">}<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><span> </span>else<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><span> </span>return 0;<o:p /></span></p>

<p class="MsoNormal"><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">}<o:p /></span></p>

<p class="MsoNormal"><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><o:p> </o:p></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">编译显示的输出信息为:</span><span><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">$gcc –Wall –c </span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">noreturn&#46;c</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">noreturn&#46;c: In function `test':<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">noreturn&#46;c:12: warning: control reaches end of non-void function<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">警告信息也很好理解,因为你定义了一个有返回值的函数</span><span lang="EN-US">test</span><span style="font-family: 宋体;">却有可能没有返回值,程序当然不知道怎么办了!</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">加上</span><span lang="EN-US">__attribute__((noreturn))</span><span style="font-family: 宋体;">则可以很好的处理类似这种问题。把</span><span lang="EN-US"><o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">extern void myexit();<o:p /></span></p>

<p align="left" style="text-indent: 21pt; text-align: left;" class="MsoNormal"><span style="font-family: 宋体;">修改为:</span><span lang="EN-US"><o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">extern void myexit() __attribute__((noreturn));<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span style="font-family: 宋体;">之后,编译不会再出现警告信息。</span><span lang="EN-US"><o:p /></span></p>

<h2><span lang="EN-US" style="font-size: 12pt; line-height: 173%; font-family: 'Times New Roman';">__attribute__ const<o:p /></span></h2>

<p align="left" style="text-indent: 21pt; text-align: left;" class="MsoNormal"><span style="font-family: 宋体;">该属性只能用于带有数值类型参数的函数上。当重复调用带有数值参数的函数时,由于返回值是相同的,所以此时编译器可以进行优化处理,除第一次需要运算外,其它只需要返回第一次的结果就可以了,进而可以提高效率。该属性主要适用于没有静态状态(</span><span lang="EN-US">static state</span><span style="font-family: 宋体;">)和副作用的一些函数,并且返回值仅仅依赖输入的参数。</span><span lang="EN-US"><o:p /></span></p>

<p align="left" style="text-indent: 21pt; text-align: left;" class="MsoNormal"><span style="font-family: 宋体;">为了说明问题,下面举个非常“糟糕”的例子,该例子将重复调用一个带有相同参数值的函数,具体如下:</span><span lang="EN-US"><o:p /></span></p>

<p align="left" style="text-indent: 21pt; text-align: left;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">extern int square(int n) <span>__attribute__((const))</span><o:p /></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">&#46;&#46;&#46;<o:p /></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';"><span> </span>for (i = 0; i < 100; i++ )<o:p /></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';"><span> </span>{<o:p /></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';"><span> </span>total += square(5) + i;<o:p /></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';"><span> </span>}<o:p /></span></pre>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">通过添加</span><span lang="EN-US">__attribute__((const))</span><span style="font-family: 宋体;">声明</span><span style="font-family: 宋体;">,编译器只调用了函数一次,以后只是直接得到了相同的一个返回值。</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">事实上,</span><span lang="EN-US">const</span><span style="font-family: 宋体;">参数不能用在带有指针类型参数的函数中,因为该属性不但影响函数的参数值,同样也影响到了参数指向的数据,它可能会对代码本身产生严重甚至是不可恢复的严重后果。</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">并且,带有该属性的函数不能有任何副作用或者是静态的状态,所以,类似</span><span lang="EN-US">getchar</span><span style="font-family: 宋体;">()或</span><span lang="EN-US">time</span><span style="font-family: 宋体;">()的函数是不适合使用该属性的。</span><span lang="EN-US"><o:p /></span></p>

<h2><span lang="EN-US" style="font-size: 12pt; line-height: 173%; font-family: 'Times New Roman';">-finstrument-functions</span><span lang="EN-US" style="font-size: 12pt; line-height: 173%; font-family: 'Times New Roman';"><o:p /></span></h2>

<p align="left" style="text-indent: 21pt; text-align: left;" class="MsoNormal"><span style="font-family: 宋体;">该参数可以使程序在编译时,在函数的入口和出口处生成</span><span lang="EN-US">instrumentation</span><span style="font-family: 宋体;">调用。恰好在函数入口之后并恰好在函数出口之前,将使用当前函数的地址和调用地址来调用下面的</span><span> </span><span lang="EN-US">profiling </span><span style="font-family: 宋体;">函数。(在一些平台上,</span><span lang="EN-US">__builtin_return_address</span><span style="font-family: 宋体;">不能在超过当前函数范围之外正常工作,所以调用地址信息可能对</span><span lang="EN-US">profiling</span><span style="font-family: 宋体;">函数是无效的。)</span><span lang="EN-US"><o:p /></span></p>

<p align="left" style="text-indent: 21pt; text-align: left;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">void __cyg_profile_func_enter(void *this_fn, void *call_site);<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">void __cyg_profile_func_exit(void *this_fn, void *call_site);<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p align="left" style="text-indent: 21pt; text-align: left;" class="MsoNormal"><span style="font-family: 宋体;">其中,第一个参数</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">this_fn</span><span style="font-family: 宋体;">是当前函数的起始地址,可在符号表中找到;第二个参数</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">call_site</span><span style="font-family: 宋体;">是指调用处地址。</span><span lang="EN-US"><o:p /></span></p>

<p align="left" style="text-indent: 21pt; text-align: left;" class="MsoNormal"><span lang="EN-US">instrumentation </span><span style="font-family: 宋体;">也可用于在其它函数中展开的内联函数。从概念上来说,</span><span lang="EN-US">profiling</span><span style="font-family: 宋体;">调用将指出在哪里进入和退出内联函数。这就意味着这种函数必须具有可寻址形式。如果函数包含内联,而所有使用到该函数的程序都要把该内联展开,这会额外地增加代码长度。如果要在</span><span lang="EN-US">C </span><span style="font-family: 宋体;">代码中使用</span><span lang="EN-US">extern inline</span><span style="font-family: 宋体;">声明</span><span style="font-family: 宋体;">,必须提供这种函数的可寻址形式。</span><span lang="EN-US"><o:p /></span></p>

<p align="left" style="text-indent: 21pt; text-align: left;" class="MsoNormal"><span style="font-family: 宋体;">可对函数指定</span><span lang="EN-US">no_instrument_function</span><span style="font-family: 宋体;">属性,在这种情况下不会进行</span><span lang="EN-US">instrumentation</span><span style="font-family: 宋体;">操作</span><span style="font-family: 宋体;">。例如,可以在以下情况下使用</span><span lang="EN-US">no_instrument_function</span><span style="font-family: 宋体;">属性:上面列出的</span><span lang="EN-US">profiling</span><span style="font-family: 宋体;">函数、高优先级的中断例程以及任何不能保证</span><span lang="EN-US">profiling</span><span style="font-family: 宋体;">正常调用的函数。</span><span lang="EN-US" style="font-size: 9pt; font-family: 宋体;"><o:p /></span></p>

<h2><span lang="EN-US" style="font-size: 12pt; line-height: 173%; font-family: 'Times New Roman';">no_instrument_function</span><span lang="EN-US" style="font-size: 12pt; line-height: 173%; font-family: 'Times New Roman';"><o:p /></span></h2>

<p align="left" style="text-indent: 21pt; text-align: left;" class="MsoNormal"><span style="font-family: 宋体;">如果使用了</span><span lang="EN-US">-finstrument-functions</span><span lang="EN-US"> </span><span style="font-family: 宋体;">,将在绝大多数用户编译的函数的入口和出口点调用</span><span lang="EN-US">profiling</span><span style="font-family: 宋体;">函数。使用该属性,将不进行</span><span lang="EN-US">instrument</span><span style="font-family: 宋体;">操作。</span><span lang="EN-US"><o:p /></span></p>

<h2><span lang="EN-US" style="font-size: 12pt; line-height: 173%; font-family: 'Times New Roman';">constructor/destructor<o:p /></span></h2>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">若函数被设定为</span><span lang="EN-US">constructor</span><span style="font-family: 宋体;">属性,则该函数会在</span><span lang="EN-US">main</span><span style="font-family: 宋体;">()函数执行之前被自动的执行。类似的,若函数被设定为</span><span lang="EN-US">destructor</span><span style="font-family: 宋体;">属性,则该函数会在</span><span lang="EN-US">main</span><span style="font-family: 宋体;">()函数执行之后或者</span><span lang="EN-US">exit</span><span style="font-family: 宋体;">()被调用后被自动的执行。拥有此类属性的函数经常隐式的用在程序的初始化数据方面。</span><span lang="EN-US"><o:p /></span></p>

<p class="MsoNormal"><span style="font-family: 宋体;">这两个属性还没有在面向对象</span><span lang="EN-US">C</span><span style="font-family: 宋体;">中实现。</span><span lang="EN-US"><o:p /></span></p>

<h2><span style="font-size: 12pt; line-height: 173%; font-family: 宋体;">同时使用多个属性</span><span lang="EN-US" style="font-size: 12pt; line-height: 173%; font-family: 'Times New Roman';"><o:p /></span></h2>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">可以在同一个函数声明里使用多个</span><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">,并且实际应用中这种情况是十分常见的。使用方式上,你可以选择两个单独的</span><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">,或者把它们写在一起,可以参考下面的例子:</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">/* </span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">把类似</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">printf</span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">的消息传递给</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">stderr </span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">并退出</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';"> */<o:p /></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">extern void die(const char *format, &#46;&#46;&#46;)<o:p /></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';"><span> </span><span>__attribute__((noreturn))<o:p /></span></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';"><span> </span>__attribute__((format(printf, 1, 2)))</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';"></span><span lang="EN-US" style="font-size: 10&#46;5pt; font-family: 'Times New Roman';"><o:p /></span></pre>
<pre><span lang="EN-US" style="font-size: 10&#46;5pt; font-family: 'Times New Roman';"><o:p> </o:p></span></pre>
<pre style="text-indent: 21pt;"><span style="font-size: 10&#46;5pt;">或者写成</span><span lang="EN-US" style="font-size: 10&#46;5pt; font-family: 'Times New Roman';"><o:p /></span></pre>
<pre><span lang="EN-US" style="font-size: 10&#46;5pt; font-family: 'Times New Roman';"><o:p> </o:p></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">extern void die(const char *format, &#46;&#46;&#46;)<o:p /></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';"><span> </span><span>__attribute__((noreturn, format(printf, 1, 2)))</span><o:p /></span></pre>
<pre><span lang="EN-US" style="font-size: 10&#46;5pt; font-family: 'Times New Roman';"><o:p> </o:p></span></pre>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">如果带有该属性的自定义函数追加到库的头文件里,那么所以调用该函数的程序都要做相应的检查。</span><span lang="EN-US"><o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<h2><span style="font-size: 12pt; line-height: 173%; font-family: 宋体;">和非</span><span lang="EN-US" style="font-size: 12pt; line-height: 173%; font-family: 'Times New Roman';">GNU</span><span style="font-size: 12pt; line-height: 173%; font-family: 宋体;">编译器的兼容性</span><span lang="EN-US" style="font-size: 12pt; line-height: 173%; font-family: 'Times New Roman';"><o:p /></span></h2>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">庆幸的是,</span><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">设计的非常巧妙,很容易作到和其它编译器保持兼容,也就是说,如果工作在其它的非</span><span lang="EN-US">GNU</span><span style="font-family: 宋体;">编译器上,可以很容易的忽略该属性。即使</span><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">使用了多个参数,也可以很容易的使用一对圆括弧进行处理,例如:</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">/* </span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">如果使用的是非</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">GNU C, </span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">那么就忽略</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">__attribute__ */<o:p /></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">#ifndef __GNUC__<o:p /></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">#<span> </span>define<span> </span>__attribute__(x)<span> </span>/*NOTHING*/<o:p /></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">#endif<o:p /></span></pre>

<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">需要说明的是,</span><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">适用于函数的声明而不是函数的定义。所以,当需要使用该属性的函数时,必须在同一个文件里进行声明,例如:</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">/* </span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">函数声明</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';"> */<o:p /></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">void die(const char *format, &#46;&#46;&#46;) <span>__attribute__((noreturn))<o:p /></span></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';"><span> </span>__attribute__((format(printf,1,2)))</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';"><o:p /></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';"><o:p> </o:p></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">void die(const char *format, &#46;&#46;&#46;)<o:p /></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">{<o:p /></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';"><span> </span>/* </span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">函数定义</span><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';"> */<o:p /></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">}<o:p /></span></pre>
<pre><span lang="EN-US" style="font-size: 10&#46;5pt; font-family: 'Times New Roman';"><o:p> </o:p></span></pre>
<pre><span style="font-size: 10&#46;5pt;">更多的属性含义参考:</span><span lang="EN-US" style="font-size: 10&#46;5pt; font-family: 'Times New Roman';"><o:p /></span></pre>
<pre><span lang="EN-US"><a href="http://gcc&#46;gnu&#46;org/onlinedocs/gcc-4&#46;0&#46;0/gcc/Function-Attributes&#46;html"><u>http://gcc&#46;gnu&#46;o ... ibutes&#46;html</u></a></span><span lang="EN-US" style="font-size: 10&#46;5pt; font-family: 'Times New Roman';"><o:p /></span></pre>
<pre><span lang="EN-US" style="font-size: 10&#46;5pt; font-family: 'Times New Roman';"><o:p> </o:p></span></pre>

<h1><span style="font-size: 14pt;">变量属性(</span><span lang="EN-US" style="font-size: 14pt; font-family: 'Times New Roman';">Variable Attributes</span><span style="font-size: 14pt;">)</span><span lang="EN-US" style="font-size: 14pt; font-family: 'Times New Roman';"><o:p /></span></h1>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">关键字</span><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">也可以对变量(</span><span lang="EN-US">variable</span><span style="font-family: 宋体;">)或结构体成员(</span><span lang="EN-US">structure field</span><span style="font-family: 宋体;">)进行属性设置。这里给出几个常用的参数的解释,更多的参数可参考本文给出的连接。</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">在使用</span><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">参数时,你也可以在参数的前后都加上“</span><span lang="EN-US">__</span><span style="font-family: 宋体;">”(两个下划线),例如,使用</span><span lang="EN-US">__aligned__</span><span style="font-family: 宋体;">而不是</span><span lang="EN-US">aligned</span><span style="font-family: 宋体;">,这样,你就可以在相应的头文件里使用它而不用关心头文件里是否有重名的宏定义。</span><span lang="EN-US"><o:p /></span></p>

<h2><span lang="EN-US" style="font-size: 12pt; line-height: 173%; font-family: 'Times New Roman';">aligned (alignment)<o:p /></span></h2>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">该属性规定变量或结构体成员的最小的对齐格式,以字节为单位。例如:</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">int x __attribute__ ((aligned (16))) = 0;<o:p /></span></pre>
<pre><span lang="EN-US" style="font-size: 10&#46;5pt; font-family: 'Times New Roman';"><o:p> </o:p></span></pre>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">编译器将以</span><span lang="EN-US">16</span><span style="font-family: 宋体;">字节(注意是字节</span><span lang="EN-US">byte</span><span style="font-family: 宋体;">不是位</span><span lang="EN-US">bit</span><span style="font-family: 宋体;">)对齐的方式分配一个变量。也可以对结构体成员变量设置该属性,例如,创建一个双字对齐的</span><span lang="EN-US">int</span><span style="font-family: 宋体;">对,可以这么写:</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">struct foo { int x[2] __attribute__ ((aligned (8))); };<o:p /></span></pre>
<pre><span lang="EN-US" style="font-size: 10&#46;5pt; font-family: 'Times New Roman';"><o:p> </o:p></span></pre>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">如上所述,你可以手动指定对齐的格式,同样,你也可以使用默认的对齐方式。如果</span><span lang="EN-US">aligned</span><span style="font-family: 宋体;">后面不紧跟一个指定的数字值,那么编译器将依据你的目标机器情况使用最大最有益的对齐方式。例如:</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';">short array[3] __attribute__ ((aligned));<o:p /></span></pre>
<pre><span lang="EN-US" style="font-size: 10&#46;5pt; font-family: 'Times New Roman';"><o:p> </o:p></span></pre>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">选择针对目标机器最大的对齐方式,可以提高拷贝操作的效率。</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span lang="EN-US">aligned</span><span style="font-family: 宋体;">属性使被设置的对象占用更多的空间,相反的,使用</span><span lang="EN-US">packed</span><span style="font-family: 宋体;">可以减小对象占用的空间。</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">需要注意的是,</span><span lang="EN-US">attribute</span><span style="font-family: 宋体;">属性的效力与你的连接器也有关,如果你的连接器最大只支持</span><span lang="EN-US">16</span><span style="font-family: 宋体;">字节对齐,那么你此时定义</span><span lang="EN-US">32</span><span style="font-family: 宋体;">字节对齐也是无济于事的。</span><span lang="EN-US"><o:p /></span></p>

<h2><span lang="EN-US" style="font-size: 12pt; line-height: 173%; font-family: 'Times New Roman';">packed<o:p /></span></h2>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">使用该属性可以使得变量或者结构体成员使用最小的对齐方式,即对变量是一字节对齐,对域(</span><span lang="EN-US">field</span><span style="font-family: 宋体;">)是位对齐。</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">下面的例子中,</span><span lang="EN-US">x</span><span style="font-family: 宋体;">成员变量使用了该属性,则其值将紧放置在</span><span lang="EN-US">a</span><span style="font-family: 宋体;">的后面:</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<pre><span lang="EN-US" style="font-size: 10&#46;5pt; font-family: 'Times New Roman';"><span> </span><span style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">struct test<o:p /></span></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';"><span> </span>{<o:p /></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';"><span> </span>char a;<o:p /></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';"><span> </span>int x[2] __attribute__ ((packed));<o:p /></span></pre>
<pre><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; font-size: 10&#46;5pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; font-family: 'Times New Roman';"><span> </span>};<o:p /></span></pre>
<pre><span lang="EN-US" style="font-size: 10&#46;5pt; font-family: 'Times New Roman';"><o:p> </o:p></span></pre>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">其它可选的属性值还可以是:</span><span lang="EN-US">cleanup</span><span style="font-family: 宋体;">,</span><span lang="EN-US">common</span><span style="font-family: 宋体;">,</span><span lang="EN-US">nocommon</span><span style="font-family: 宋体;">,</span><span lang="EN-US">deprecated</span><span style="font-family: 宋体;">,</span><span lang="EN-US">mode</span><span style="font-family: 宋体;">,</span><span lang="EN-US">section</span><span style="font-family: 宋体;">,</span><span lang="EN-US">shared</span><span style="font-family: 宋体;">,</span><span lang="EN-US">tls_model</span><span style="font-family: 宋体;">,</span><span lang="EN-US">transparent_union</span><span style="font-family: 宋体;">,</span><span lang="EN-US">unused</span><span style="font-family: 宋体;">,</span><span lang="EN-US">vector_size</span><span style="font-family: 宋体;">,</span><span lang="EN-US">weak</span><span style="font-family: 宋体;">,</span><span lang="EN-US">dllimport</span><span style="font-family: 宋体;">,</span><span lang="EN-US">dlexport</span><span style="font-family: 宋体;">等,</span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">详细信息可参考:</span></p>

<p class="MsoNormal"><code><span lang="EN-US" style="font-size: 12pt;"><a href="http://gcc&#46;gnu&#46;org/onlinedocs/gcc-4&#46;0&#46;0/gcc/Variable-Attributes&#46;html#Variable-Attributes"><span style="font-size: 10&#46;5pt;"><u>http://gcc&#46;gnu&#46;o ... Variable-Attributes</u></span></a></span></code><code><span lang="EN-US" style="font-size: 12pt;"><o:p /></span></code></p>

<h1><span style="font-size: 14pt;">类型属性(</span><span lang="EN-US" style="font-size: 14pt; font-family: 'Times New Roman';">Type Attribute</span><span style="font-size: 14pt;">)</span><code><span lang="EN-US" style="font-size: 14pt; font-family: 'Times New Roman';"><o:p /></span></code></h1>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">关键字</span><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">也可以对结构体(</span><span lang="EN-US">struct</span><span style="font-family: 宋体;">)或共用体(</span><span lang="EN-US">union</span><span style="font-family: 宋体;">)进行属性设置。大致有六个参数值可以被设定,即:</span><span lang="EN-US">aligned, packed, transparent_union, unused, deprecated </span><span style="font-family: 宋体;">和</span><span lang="EN-US"> may_alias</span><span style="font-family: 宋体;">。</span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">在使用</span><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">参数时,你也可以在参数的前后都加上“</span><span lang="EN-US">__</span><span style="font-family: 宋体;">”(两个下划线),例如,使用</span><span lang="EN-US">__aligned__</span><span style="font-family: 宋体;">而不是</span><span lang="EN-US">aligned</span><span style="font-family: 宋体;">,这样,你就可以在相应的头文件里使用它而不用关心头文件里是否有重名的宏定义。</span><span lang="EN-US"><o:p /></span></p>

<h2><span lang="EN-US" style="font-size: 12pt; line-height: 173%; font-family: 'Times New Roman';">aligned (alignment)<o:p /></span></h2>

<p class="MsoNormal"><span style="font-family: 宋体;">该属性设定一个指定大小的对齐格式(以字节为单位),例如:</span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">struct S { short f[3]; } __attribute__ ((aligned (8)));<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">typedef int more_aligned_int __attribute__ ((aligned (8)));<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p style="text-indent: 24pt;" class="MsoNormal"><code><span style="font-size: 12pt;">该声明将强制编译器确保(尽它所能)变量类型为<span lang="EN-US">struct S</span>或者<span lang="EN-US">more-aligned-int</span>的变量在分配空间时采用<span lang="EN-US">8</span>字节对齐方式。</span></code><code><span lang="EN-US" style="font-size: 12pt;"><o:p /></span></code></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">如上所述,你可以手动指定对齐的格式,同样,你也可以使用默认的对齐方式。如果</span><span lang="EN-US">aligned</span><span style="font-family: 宋体;">后面不紧跟一个指定的数字值,那么编译器将依据你的目标机器情况使用最大最有益的对齐方式。例如:</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">struct S { short f[3]; } __attribute__ ((aligned));<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">这里,如果</span><span lang="EN-US">sizeof</span><span style="font-family: 宋体;">(</span><span lang="EN-US">short</span><span style="font-family: 宋体;">)的大小为</span><span lang="EN-US">2</span><span style="font-family: 宋体;">(</span><span lang="EN-US">byte</span><span style="font-family: 宋体;">),那么,</span><span lang="EN-US">S</span><span style="font-family: 宋体;">的大小就为</span><span lang="EN-US">6</span><span style="font-family: 宋体;">。取一个</span><span lang="EN-US">2</span><span style="font-family: 宋体;">的次方值,使得该值大于等于</span><span lang="EN-US">6</span><span style="font-family: 宋体;">,则该值为</span><span lang="EN-US">8</span><span style="font-family: 宋体;">,所以编译器将设置</span><span lang="EN-US">S</span><span style="font-family: 宋体;">类型的对齐方式为</span><span lang="EN-US">8</span><span style="font-family: 宋体;">字节。</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span lang="EN-US">aligned</span><span style="font-family: 宋体;">属性使被设置的对象占用更多的空间,相反的,使用</span><span lang="EN-US">packed</span><span style="font-family: 宋体;">可以减小对象占用的空间。</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">需要注意的是,</span><span lang="EN-US">attribute</span><span style="font-family: 宋体;">属性的效力与你的连接器也有关,如果你的连接器最大只支持</span><span lang="EN-US">16</span><span style="font-family: 宋体;">字节对齐,那么你此时定义</span><span lang="EN-US">32</span><span style="font-family: 宋体;">字节对齐也是无济于事的。</span><span lang="EN-US"><o:p /></span></p>

<h2><span lang="EN-US" style="font-size: 12pt; line-height: 173%; font-family: 'Times New Roman';">packed<o:p /></span></h2>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">使用该属性对</span><span lang="EN-US">struct</span><span style="font-family: 宋体;">或者</span><span lang="EN-US">union</span><span style="font-family: 宋体;">类型进行定义,设定其类型的每一个变量的内存约束。当用在</span><span lang="EN-US">enum</span><span style="font-family: 宋体;">类型定义时,暗示了应该使用最小完整的类型(</span><span lang="EN-US">it indicates that the smallest integral type should be used</span><span style="font-family: 宋体;">)。</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">下面的例子中,</span><span lang="EN-US">my-packed-struct</span><span style="font-family: 宋体;">类型的变量数组中的值将会紧紧的靠在一起,但内部的成员变量</span><span lang="EN-US">s</span><span style="font-family: 宋体;">不会被“</span><span lang="EN-US">pack</span><span style="font-family: 宋体;">”,如果希望内部的成员变量也被</span><span lang="EN-US">packed</span><span style="font-family: 宋体;">的话,</span><span lang="EN-US">my-unpacked-struct</span><span style="font-family: 宋体;">也需要使用</span><span lang="EN-US">packed</span><span style="font-family: 宋体;">进行相应的约束。</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">struct my_unpacked_struct<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">{<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><span> </span>char c;<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><span> </span>int i;<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">};<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><span> </span><o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">struct my_packed_struct <o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">{<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><span> </span>char c;<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><span> </span>int<span> </span>i;<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"><span> </span>struct my_unpacked_struct s;<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US" style="background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">}__attribute__ ((__packed__));<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">其它属性的含义见:</span><span lang="EN-US"><o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US"><a href="http://gcc&#46;gnu&#46;org/onlinedocs/gcc-4&#46;0&#46;0/gcc/Type-Attributes&#46;html#Type-Attributes"><u>http://gcc&#46;gnu&#46;o ... tml#Type-Attributes</u></a><o:p /></span></p>

<h2><span style="font-size: 12pt; line-height: 173%; font-family: 宋体;">变量属性与类型属性举例</span><span lang="EN-US" style="font-size: 12pt; line-height: 173%; font-family: 'Times New Roman';"><o:p /></span></h2>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">下面的例子中使用</span><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">属性定义了一些结构体及其变量,并给出了输出结果和对结果的分析。</span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">程序代码为:</span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">struct p<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">{<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">int a;<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">char b;<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">char c;<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">}__attribute__((aligned(4))) pp;<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">struct q<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">{<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">int a;<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">char b;<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">struct n qn;<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">char c;<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">}__attribute__((aligned(8))) qq;<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">int main()<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">{<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">printf("sizeof(int)=%d,sizeof(short)=%d&#46;sizeof(char)=%d\n",sizeof(int),sizeof(short),sizeof(char));<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">printf("pp=%d,qq=%d \n", sizeof(pp),sizeof(qq));<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">return 0;<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">}<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">输出结果:</span><span lang="EN-US"><o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">sizeof(int)=4,sizeof(short)=2&#46;sizeof(char)=1<o:p /></span></p>

<p align="left" style="text-align: left;" class="MsoNormal"><span lang="EN-US">pp=8,qq=24<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">分析</span><span style="font-family: 宋体;">:</span><span lang="EN-US"><o:p /></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p class="MsoNormal"><span lang="EN-US">sizeof(pp):<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US">sizeof(a)+ sizeof(b)+ sizeof(c)=4+1+1=6<2<sup>3</sup>=8= sizeof(pp)<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US">sizeof(qq):<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US">sizeof(a)+ sizeof(b)=4+1=5<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US">sizeof(qn)=8;</span><span style="font-family: 宋体;">即</span><span lang="EN-US">qn</span><span style="font-family: 宋体;">是采用</span><span lang="EN-US">8</span><span style="font-family: 宋体;">字节对齐的,所以要在</span><span lang="EN-US">a</span><span style="font-family: 宋体;">,</span><span lang="EN-US">b</span><span style="font-family: 宋体;">后面添</span><span lang="EN-US">3</span><span style="font-family: 宋体;">个空余字节,然后才能存储</span><span lang="EN-US">qn</span><span style="font-family: 宋体;">,</span><span lang="EN-US"><o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US">4+1+</span><span style="font-family: 宋体;">(</span><span lang="EN-US">3</span><span style="font-family: 宋体;">)</span><span lang="EN-US">+8+1=17<o:p /></span></p>

<p class="MsoNormal"><span style="font-family: 宋体;">因为</span><span lang="EN-US">qq</span><span style="font-family: 宋体;">采用的对齐是</span><span lang="EN-US">8</span><span style="font-family: 宋体;">字节对齐,所以</span><span lang="EN-US">qq</span><span style="font-family: 宋体;">的大小必定是</span><span lang="EN-US">8</span><span style="font-family: 宋体;">的整数倍,即</span><span lang="EN-US">qq</span><span style="font-family: 宋体;">的大小是一个比</span><span lang="EN-US">17</span><span style="font-family: 宋体;">大又是</span><span lang="EN-US">8</span><span style="font-family: 宋体;">的倍数的一个最小值,由此得到</span><span lang="EN-US"><o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US">17<2<sup>4</sup>+8=24= sizeof(qq)<o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<p style="text-indent: 21pt;" class="MsoNormal"><span style="font-family: 宋体;">更详细的介绍见:</span><span lang="EN-US"><a href="http://gcc&#46;gnu&#46;org/"><u>http://gcc&#46;gnu&#46;org</u></a><o:p /></span></p>

<p align="left" style="text-indent: 17&#46;95pt; text-align: left;" class="MsoNormal"><span style="font-family: 宋体;">下面是一些便捷的连接:</span><span lang="EN-US"><a href="http://gcc&#46;gnu&#46;org/onlinedocs/gcc-4&#46;0&#46;0/gcc/Function-Attributes&#46;html"><u>GCC 4&#46;0 Function Attributes</u></a></span><span style="font-family: 宋体;">;</span><span lang="EN-US"><a href="http://gcc&#46;gnu&#46;org/onlinedocs/gcc-4&#46;0&#46;0/gcc/Variable-Attributes&#46;html"><u>GCC 4&#46;0 Variable Attributes</u></a> </span><span style="font-family: 宋体;">;</span><span lang="EN-US"><a href="http://gcc&#46;gnu&#46;org/onlinedocs/gcc-4&#46;0&#46;0/gcc/Type-Attributes&#46;html"><u>GCC 4&#46;0 Type Attributes</u></a> </span><span style="font-family: 宋体;">;</span><span lang="EN-US"><a href="http://gcc&#46;gnu&#46;org/onlinedocs/gcc-3&#46;2/gcc/Function-Attributes&#46;html"><u>GCC 3&#46;2 Function Attributes</u></a> </span><span style="font-family: 宋体;">;</span><span lang="EN-US"><a href="http://gcc&#46;gnu&#46;org/onlinedocs/gcc-3&#46;2/gcc/Variable-Attributes&#46;html"><u>GCC 3&#46;2 Variable Attributes</u></a> </span><span style="font-family: 宋体;">;</span><span lang="EN-US"><a href="http://gcc&#46;gnu&#46;org/onlinedocs/gcc-3&#46;2/gcc/Type-Attributes&#46;html"><u>GCC 3&#46;2 Type Attributes</u></a> </span><span style="font-family: 宋体;">;</span><span lang="EN-US"><a href="http://gcc&#46;gnu&#46;org/onlinedocs/gcc-3&#46;1/gcc/Function-Attributes&#46;html"><u>GCC 3&#46;1 Function Attributes</u></a> </span><span style="font-family: 宋体;">;</span><span lang="EN-US"><a href="http://gcc&#46;gnu&#46;org/onlinedocs/gcc-3&#46;1/gcc/Variable-Attributes&#46;html"><u>GCC 3&#46;1 Variable Attributes</u></a> <o:p /></span></p>

<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>

<h1><span lang="EN-US" style="font-size: 14pt; font-family: 'Times New Roman';">Reference</span><span style="font-size: 14pt;">:</span><span lang="EN-US" style="font-size: 14pt; font-family: 'Times New Roman';"><o:p /></span></h1>

<p class="MsoNormal"><span lang="EN-US">1</span><span style="font-family: 宋体;">.有关</span><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">的相对简单的介绍:</span><span lang="EN-US"><a href="http://www&#46;unixwiz&#46;net/techtips/gnu-c-attributes&#46;html"><u>http://www&#46;unixwiz&# ... ibutes&#46;html</u></a><o:p /></span></p>

<span lang="EN-US">2</span><span style="font-family: 宋体;">.</span><span lang="EN-US">__attribute__</span><span style="font-family: 宋体;">详细介绍:</span><span lang="EN-US"><a href="http://gcc&#46;gnu&#46;org/"><u>http://gcc&#46;gnu&#46;org</u></a></span><br />
<br />
<div style="text-align: right;"><span class="content" style="font-weight: bold;">作者:聂飞</span><br />

</div>

4917

主题

5879

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34382
沙发
 楼主| 发表于 2011-1-12 21:57:39 | 只看该作者

__attribute__((hot))|__attribute__((cold))

__attribute__((hot))
函数前面使用这个扩展,表示该函数会被经常调用到,在编译链接时要对其优化,或说是将它和其他同样热(hot)的函数放到一块,这样有利于缓存的存取。

__attribute__((cold))

Hint that the marked function is "cold" and should be optimized for size, predicted as unlikely for branch prediction, and/or placed near other "cold" functions (so other functions can have improved cache locality).
函数前面使用这个扩展,表示该函数比较冷门,这样在分支预测机制里就不会对该函数进行预取,或说是将它和其他同样冷门(cold)的函数放到一块,这样它就很可能不会被放到缓存中来,而让更热门的指令放到缓存中。

关于分支预测机制可以参考:http://www.groad.net/bbs/read.php?tid-1456.html
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2024-5-10 19:15 , Processed in 0.064875 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表