c语言 内嵌函数,gcc对C语言的扩展:内嵌函数(Nested Function)-站长资讯中心

2023-11-20 20:40

本文主要是介绍c语言 内嵌函数,gcc对C语言的扩展:内嵌函数(Nested Function)-站长资讯中心,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

c4468b3f4df77e96b0a416fa2a870fba.png

所谓内嵌函数就是定义于另一个函数内部的函数.(GNU C 不支持内嵌函数) 内嵌函数名在他被定义的块中是局部有效的。例如这里我们定义了一个函数squre并调用了他两次:

foo ( double a, double b )

{

double square (double z) { return z * z; }

return square (a) square (b);

}

包含内嵌函数的函数内的任何变量对于内嵌函数都是可见的。这称为词法作用域(lexical scoping)。例如这里我们给出一个内嵌函数,他使用了一个继承得到的变量,叫offset:

bar (int *array, int offset, int size)

{

int access (int *array, int index)

{ return array[index offset]; }

int i;

...

for (i = 0; i < size; i )

... access (array, i) ...

}

函数内部,允许变量定义的地方就能定义内嵌函数:也就是说,在任何程式块(block)内,第一条语句之前。从内嵌函数名所在有效域之外通过存储他的地址或把他的地址传给其他函数来调用他也是可行的:

hack (int *array, int size)

{

void store (int index, int value)

{ array[index] = value; }

intermediate (store, size);

}

这里,函数store的地址作为参数传给了函数intermediate。假如intermediate调用了store,store的参数就会被存储到array里面了。但是这种方式只用当包含store的包含函数(hack)没有返回时才有效。

假如您在当包含函数已退出后再通过地址方式来调用内嵌函数, 结果不可预料。 假如当您试着在内嵌函数的包含域退出之后调用他,而他使用了某些已不可见的变量,您可能很幸运的得到正确结果,但是去冒这种风险并不明智。然而,假如内嵌函数没有使用到任何已不可见的量则应该是安全的。

GCC使用了称为弹床(tramplines)的技术实现内嵌函数的地址的获取。关于该技术的文章能够在

http://people.debian.org/~aaronl/Usenix88-lexic.pdf 找到。

假如在包含函数中显式定义了一个标签,一个内嵌函数能够跳转到从包含函数中继承过来的标签处。调用goto进行跳转的内嵌将立即返回(同时也使得中介函数也返回)到包含函数。例如:

bar (int *array, int offset, int size)

{

__label__ failure;

int access (int *array, int index)

{

if (index > size)

goto failure;

return array[index offset];

}

int i;

...

for (i = 0; i < size; i )

... access (array, i) ...

...

return 0;

/* Control comes here from access

if it detects an error. */

failure:

return -1;

}

一个内嵌函数总是使用文档内部链接方式。声明一个带extern的内嵌函数将产生错误。假如您需要在定义一个内嵌函数前声明他,要使用auto关键字(除此种情况之外,在函数定义时使用auto没有任何意义)。

bar (int *array, int offset, int size)

{

__label__ failure;

auto int access (int *, int);

...

int access (int *array, int index)

{

if (index > size)

goto failure;

return array[index offset];

}

...

}

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com

特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

这篇关于c语言 内嵌函数,gcc对C语言的扩展:内嵌函数(Nested Function)-站长资讯中心的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/397301

相关文章

Mybatis对MySQL if 函数的不支持问题解读

《Mybatis对MySQLif函数的不支持问题解读》接手项目后,为了实现多租户功能,引入了Mybatis-plus,发现之前运行正常的SQL语句报错,原因是Mybatis不支持MySQL的if函... 目录MyBATis对mysql if 函数的不支持问题描述经过查询网上搜索资料找到原因解决方案总结Myb

Python容器转换与共有函数举例详解

《Python容器转换与共有函数举例详解》Python容器是Python编程语言中非常基础且重要的概念,它们提供了数据的存储和组织方式,下面:本文主要介绍Python容器转换与共有函数的相关资料,... 目录python容器转换与共有函数详解一、容器类型概览二、容器类型转换1. 基本容器转换2. 高级转换示

Spring配置扩展之JavaConfig的使用小结

《Spring配置扩展之JavaConfig的使用小结》JavaConfig是Spring框架中基于纯Java代码的配置方式,用于替代传统的XML配置,通过注解(如@Bean)定义Spring容器的组... 目录JavaConfig 的概念什么是JavaConfig?为什么使用 JavaConfig?Jav

C语言逗号运算符和逗号表达式的使用小结

《C语言逗号运算符和逗号表达式的使用小结》本文详细介绍了C语言中的逗号运算符和逗号表达式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习... 在C语言中逗号“,”也是一种运算符,称为逗号运算符。 其功能是把两个表达式连接其一般形式为:表达

Go语言实现桥接模式

《Go语言实现桥接模式》桥接模式是一种结构型设计模式,它将抽象部分与实现部分分离,使它们可以独立地变化,本文就来介绍一下了Go语言实现桥接模式,感兴趣的可以了解一下... 目录简介核心概念为什么使用桥接模式?应用场景案例分析步骤一:定义实现接口步骤二:创建具体实现类步骤三:定义抽象类步骤四:创建扩展抽象类步

GO语言实现串口简单通讯

《GO语言实现串口简单通讯》本文分享了使用Go语言进行串口通讯的实践过程,详细介绍了串口配置、数据发送与接收的代码实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 目录背景串口通讯代码代码块分解解析完整代码运行结果背景最近再学习 go 语言,在某宝用5块钱买了个

SpringBoot的内嵌和外置tomcat的实现方式

《SpringBoot的内嵌和外置tomcat的实现方式》本文主要介绍了在SpringBoot中定制和修改Servlet容器的配置,包括内嵌式和外置式Servlet容器的配置方法,文中通过示例代码介绍... 目录1.内嵌如何定制和修改Servlet容器的相关配置注册Servlet三大组件Servlet注册详

pandas使用apply函数给表格同时添加多列

《pandas使用apply函数给表格同时添加多列》本文介绍了利用Pandas的apply函数在DataFrame中同时添加多列,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习... 目录一、Pandas使用apply函数给表格同时添加多列二、应用示例一、Pandas使用apply函

Python中Namespace()函数详解

《Python中Namespace()函数详解》Namespace是argparse模块提供的一个类,用于创建命名空间对象,它允许通过点操作符访问数据,比字典更易读,在深度学习项目中常用于加载配置、命... 目录1. 为什么使用 Namespace?2. Namespace 的本质是什么?3. Namesp

MySQL中如何求平均值常见实例(AVG函数详解)

《MySQL中如何求平均值常见实例(AVG函数详解)》MySQLavg()是一个聚合函数,用于返回各种记录中表达式的平均值,:本文主要介绍MySQL中用AVG函数如何求平均值的相关资料,文中通过代... 目录前言一、基本语法二、示例讲解1. 计算全表平均分2. 计算某门课程的平均分(例如:Math)三、结合