6.7.4 函数说明符

语法

1、function-specifier:

inline

_Noreturn

约束

2、函数说明符应该只能被用在对一个函数标识符的声明中。

3、对一个含有外部连接函数的内联定义,不应该包含含有静态或线程存储周期的可修改对象的定义,并且不应该含有对带有内部连接的一个标识符的引用。[译者注:比如

static int ss = ;

extern inline void hello(int a);

inline void hello(int a)
{
static int s; // 不应该定义可修改的静态变量 s = a; ss += a; // 不应该引用具有内部连接的变量
}

这里要注意的是,所谓的“不应该”是指程序员应该尽量避免这种使用方式,但编译器实现可以允许这种写法。因为,对于上述代码片段如果是写在一个头文件(.h)中时,那么对于不同翻译单元,它们的行为可能是不同的。

4、在一个主机端环境,在对main函数的声明中不应该出现任何函数说明符。

语义

5、一个函数说明符可以出现多次;行为就跟只出现一次是一样的。

6、用inline函数说明符声明的一个函数是一个内联函数。将一个函数作为一个内联函数提议了,对那个函数的调用尽可能地快。[注:比如,通过对普通的函数调用机制使用一种替换,诸如“内联替换”。内联替换并不是字面上的替换,它也不创建一个新的函数。从而,比如在函数体内使用一个宏扩展,在函数体出现的那一点而不是函数被调用的那一点,使用了它所具有的定义;并且标识符引用函数体发生的作用域内的声明。同样地,函数具有一单个地址,不管内联定义除了外部定义以外还发生的次数。]

7、任一具有内部连接的函数可以是一个内联函数。对于具有外部连接的函数,要应用以下限制:如果一个函数用一个inline函数说明符,那么它也应该被定义在同一个翻译单元。如果一个翻译单元中,一个函数的所有文件作用域内的声明包含了inline函数说明符,且没有extern,那么在那个翻译单元中的定义是一个内联定义。一个内联定义并不提供对该函数的一个外部定义,并且并不禁止在另一个翻译单元提供一个外部定义。一个内联定义提供了对一个外部定义的替代品,这样一个翻译单元可以用来在同一个翻译单元中实现对该函数的任一调用。对该函数的一次调用是否使用内联定义还是使用外部定义是未指定的。[注:由于一个内联定义区别于相应的外部定义,也区别于在其它翻译单元内的内联定义,因而所有具有静态存储周期的相应对象([译者注:这些静态对象定义在内联函数中]),在每个定义中也是独立分开的。]

8、用一个_Noreturn函数说明符声明的一个函数不应该返回到其调用者。

推荐的实践

9、如果用一个_Noreturn函数说明符声明的一个函数中出现了能够返回到其调用者,那么实现应该对这种情况生成一条诊断消息。

10、例1 具有外部连接的一个内联函数的声明,可以产生一个外部定义,要么是一个仅在翻译单元内可用的定义。带有extern的一个文件作用域声明创建一个外部定义。以下例子展示了一整个翻译单元。

inline double fahr(double t)
{
return (9.0 * t) / 5.0 + 32.0;
} inline double cels(double t)
{
return (5.0 * (t - 32.0)) / 9.0;
} extern double fahr(double); // 创建了一个外部定义 double convert(int is_fahr, double temp)
{
/* 一个翻译器可以执行内联替换 */
return is_fahr? cels(temp) : fahr(temp);
}

11、注意,对fahr的定义是一个外部定义,因为fahr也用extern声明,但对cels的定义是内联定义。因为,cels具有外部连接且被引用,一个外部定义必须出现在另一个翻译单元中(见6.9);内联定义与外部定义是有所不同的,并且任意一个都可用于函数调用。

12、例2

_Noreturn void f() {
abort(); // OK
} _Noreturn void g(int i) {
// 引发未定义的行为,如果 i <= 0
if( i > )
abort();
}

最新文章

  1. ReactJS入门(一)—— 初步认识React
  2. BZOJ 4581: [Usaco2016 Open]Field Reduction
  3. c#数据绑定(3)——数据转化为信息
  4. LeetCode - 50. Pow(x, n)
  5. AIR ANE(本机扩展)使用中的一些问题(Android平台)
  6. vi编辑文件出现Can&#39;t open file for writing错误
  7. Android与OpenCV——重新下载安装和OpenCV匹配的Android开发环境
  8. asp.net 中excel 导入数据库
  9. 五十行javascript代码实现简单的双向数据绑定
  10. 【java设计模式】责任链模式
  11. 关于SQL性能优化的十条经验
  12. 优化:mysql查询最近一条记录
  13. unity游戏热更新
  14. 11G新特性 -- archival(long-term)backups
  15. lamda匿名函数(与sorted(),filter(),map() 一起用), 递归函数, 二分查找
  16. Win7下的C盘重新划分为两个盘
  17. 供安全工程师实用的SOC模型
  18. 中间人攻击-MITM攻击
  19. LUA中相同签名函数覆盖
  20. Array方法学习小结

热门文章

  1. eclipse更改jdk版本(1.6》1.7 以此类推)
  2. spring框架面試題目
  3. 要求用Windows下批处理和Linux下的shell脚本完成,两文本交替输出
  4. git如何统计代码行数
  5. Deepin Create/Delete Folder refresh
  6. mysql存储html代码之导出后无法导入问题
  7. PHP var_dump() 函数
  8. Java与设计模式之单例模式(下) 安全的单例模式
  9. 20190710用控制台启动一个wcf服务
  10. JDBC 操作