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();
}

ISO/IEC 9899:2011 条款6.7.4——函数说明符的更多相关文章

  1. ISO/IEC 9899:2011 条款6.9.1——函数定义

    6.9.1 函数定义 语法 1.function-definition: declaration-specifiers    declarator    declaration-listopt     ...

  2. ISO/IEC 9899:2011 条款6.7.5——对齐说明符

    6.7.5 对齐说明符 语法 1.alignment-specifier: _Alignas    (    type-name    ) _Alignas    (    constant-expr ...

  3. ISO/IEC 9899:2011 条款6.7.2——类型说明符

    6.7.2 类型说明符 语法 1.type-specifier: void char short int long float double signed unsigned _Bool _Comple ...

  4. ISO/IEC 9899:2011 条款3——术语、定义与符号

    3. 术语.定义与符号 1.对于此国际标准的意图,应用了以下定义.其它术语是在用斜体类型或一个语法规则左侧出现的地方定义.在本国际标准中所显式定义的术语不被假定为对其它地方所定义的类似术语的隐式引用. ...

  5. ISO/IEC 9899:2011 条款5——5.2.1 字符集

    5.2.1 字符集 1.两个字符集和它们相关联的依次顺序应该被定义:写在源文件中的集合(源字符集),以及在执行环境中被解释的集合(执行字符集).每个集合此外被划分为一个基本字符集,其内容由本子条款给出 ...

  6. ISO/IEC 9899:2011 条款6.4.2——标识符

    6.4.2 标识符 6.4.2.1 通用 语法 1.identifier: identifier-nodigit identifier    identifier-nondigit identifie ...

  7. ISO/IEC 9899:2011 条款6.4.3——通用字符名

    6.4.3 通用字符名 语法 1.通用字符名: universal_character-name: \u hex-quad(四位十六进制数) \U hex-quad hex-quad hex-quad ...

  8. ISO/IEC 9899:2011 条款5——5.1.2 执行环境

    5.1.2 执行环境 1.定义了两个执行环境:独立式(freestanding)以及宿主的(hosted).在这两种情况下,当一个派定的C函数被执行环境调用时,程序就启动.所有具有静态存储周期的对象应 ...

  9. ISO/IEC 9899:2011 条款4——标准顺从

    4. 标准顺从 1.在本国际标准中,“应该”被解释为对一个实现或一个程序的要求:相反地,“不该”被解释为禁用. 2.如果违反了出现在一个强制规定或运行时强制规定之外的“应该”或“不该”要求,那么该行为 ...

随机推荐

  1. vue和react原理性知识点

    Vue组件如何通信? computed和watch有什么区别? Vue是如何实现双向绑定的? Proxy与Object.defineProperty的优劣对比? 你是如何理解Vue的响应式系统的? 既 ...

  2. DT开发笔记-Cookie作用域的设置

    当网站任意一个模块绑定了二级域名或者会员公司主页开启了二级域名时,必须设置cookie作用域,否则会导致二级域名站点不能显示正确的登录状态,js权限错误等问题(例如评论框显示不完全的现象). 进入网站 ...

  3. Redis 中的高级数据类型

    5个基础数据类型 高级功能 ① HyperLogLog (参考) 供不精确的去重计数功能,比较适合用来做大规模数据的去重统计,例如统计 UV > PFADD visitors alice bob ...

  4. C#使用托管程序连接Oracle数据库(Oracle.ManagedDataAccess.dll)

    一.概述 Oracle Data Provider for  .NET, Managed Driver: Oracle官方的托管数据库访问组件,单DLL,Oracle.ManagedDataAcces ...

  5. Burp Suite的代理Brup Proxy的使用详解

    Burp Proxy 是Burp Suite以用户驱动测试流程功能的核心,通过代理模式,可以让我们拦截.查看.修改所有在客户端和服务端之间传输的数据.  

  6. tcp的三次握手和四次挥手转自https://www.jianshu.com/p/d3725391af59

    三次握手(three-way handshaking) 1.背景:TCP位于传输层,作用是提供可靠的字节流服务,为了准确无误地将数据送达目的地,TCP协议采纳三次握手策略. 2.原理: 1)发送端首先 ...

  7. 项目架构&架构部署&网站分析&网站优化

    一.架构演变 一个项目至少由三层内容组成:web访问层.数据库层.存储层 初级阶段 单体阶段 常见场景:项目初期 部署特点:所有应用服务都在一台主机 应用特点:开发简单 应用/数据分离阶段 常见场景: ...

  8. How To Set The Hostname On Ubuntu Or Debian?

    $ sudo hostnamectl set-hostname your-hostname $ sudo vim /etc/hosts Open the hosts file and add the ...

  9. 转 Storm JAVA_HOME is incorrectly set.

    问题可能有两个原因: 1.在环境变量中未设置JAVA_HOME变量名称. 解决办法: 在环境变量中添加. 或者在storm中的bin文件下有一个storm-config.cmd,使用文本打开,查询JA ...

  10. 悬线法DP总结

    悬线法DP总结 问题模型 求满足某种条件(如01交替)的最大矩形(正方形) 思想 先预处理出\(ml[i][j],mr[i][j],mt[i][j]\),分别表示当前位置\((i,j)\)能向左扩展到 ...