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. Spring4- 01 - Spring框架简介及官方压缩包目录介绍- Spring IoC 的概念 - Spring hello world环境搭建

    一. Spring 框架简介及官方压缩包目录介绍 主要发明者:Rod Johnson 轮子理论推崇者: 2.1 轮子理论:不用重复发明轮子. 2.2 IT 行业:直接使用写好的代码. Spring 框 ...

  2. P1402 酒店之王[网络瘤(正解)/匈牙利(错解)]

    题目描述 XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化.由于很多来住店的旅客有自己喜好的房间色调.阳光等,也有自己所爱的菜,但是该酒店只有p间房间,一天只有固定的q道不同的菜. ...

  3. python_并发编程——锁

    多进程模拟买票~ import time import json from multiprocessing import Process class Show(Process): #查 def run ...

  4. memorization-根据输入重新计算render的数据

    在实际开发过程中,经常遇到根据props和state变化,重新计算“渲染阶段”需要的数据的情况. 如:根据输入的值实时过滤select列表,或者表格数据(查询过滤). 问题特点: 1. 每次渲染都会调 ...

  5. learning java AWT 常见组件

    import javax.swing.*; import java.awt.*; public class CommonComponent { Frame f = new Frame("te ...

  6. Windows异常

    一.什么是异常 异常指的是在程序运行过程中发生的异常事件,通常是由外部问题(如硬件错误.输入错误)所导致的.简单来说异常就是对于非预期状况的处理,当我们在运行某个程序时出现了异常状况,就会进入异常处理 ...

  7. Python学习之--用户输入以及运算

    一. 用户输入:input 1. 函数input() 让程序暂停运行,等待用户输入一些文本. 2.使用int()将字符串转为数值 二.运算:+-*. 1.求模运算符 (%)将两个数相除并返回余数: 2 ...

  8. 交互设计算法基础(3) - Quick Sort

    int pivotIndex, pivot, swapIndex; void swap(int[] arr, int x, int y) { int temp = arr[x]; arr[x] = a ...

  9. 《挑战30天C++入门极限》C++的iostream标准库介绍(2)

        C++的iostream标准库介绍(2) 接下来我们继续看一下C++风格的串流控制,C++引入了ostringstream.istringstream.stringstream这三个类,要使用 ...

  10. P2016 战略游戏——树形DP大水题

    P2016 战略游戏 树形DP 入门题吧(现在怎么是蓝色标签搞不懂): 注意是看见每一条边而不是每一个点(因为这里错了好几次): #include<cstdio> #include< ...