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

相关文章

Django中的函数视图和类视图以及路由的定义方式

《Django中的函数视图和类视图以及路由的定义方式》Django视图分函数视图和类视图,前者用函数处理请求,后者继承View类定义方法,路由使用path()、re_path()或url(),通过in... 目录函数视图类视图路由总路由函数视图的路由类视图定义路由总结Django允许接收的请求方法http

Go语言使用select监听多个channel的示例详解

《Go语言使用select监听多个channel的示例详解》本文将聚焦Go并发中的一个强力工具,select,这篇文章将通过实际案例学习如何优雅地监听多个Channel,实现多任务处理、超时控制和非阻... 目录一、前言:为什么要使用select二、实战目标三、案例代码:监听两个任务结果和超时四、运行示例五

C语言中%zu的用法解读

《C语言中%zu的用法解读》size_t是无符号整数类型,用于表示对象大小或内存操作结果,%zu是C99标准中专为size_t设计的printf占位符,避免因类型不匹配导致错误,使用%u或%d可能引发... 目录size_t 类型与 %zu 占位符%zu 的用途替代占位符的风险兼容性说明其他相关占位符验证示

MySQL常用字符串函数示例和场景介绍

《MySQL常用字符串函数示例和场景介绍》MySQL提供了丰富的字符串函数帮助我们高效地对字符串进行处理、转换和分析,本文我将全面且深入地介绍MySQL常用的字符串函数,并结合具体示例和场景,帮你熟练... 目录一、字符串函数概述1.1 字符串函数的作用1.2 字符串函数分类二、字符串长度与统计函数2.1

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

C语言进阶(预处理命令详解)

《C语言进阶(预处理命令详解)》文章讲解了宏定义规范、头文件包含方式及条件编译应用,强调带参宏需加括号避免计算错误,头文件应声明函数原型以便主函数调用,条件编译通过宏定义控制代码编译,适用于测试与模块... 目录1.宏定义1.1不带参宏1.2带参宏2.头文件的包含2.1头文件中的内容2.2工程结构3.条件编

Go语言并发之通知退出机制的实现

《Go语言并发之通知退出机制的实现》本文主要介绍了Go语言并发之通知退出机制的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、通知退出机制1.1 进程/main函数退出1.2 通过channel退出1.3 通过cont

Go语言编译环境设置教程

《Go语言编译环境设置教程》Go语言支持高并发(goroutine)、自动垃圾回收,编译为跨平台二进制文件,云原生兼容且社区活跃,开发便捷,内置测试与vet工具辅助检测错误,依赖模块化管理,提升开发效... 目录Go语言优势下载 Go  配置编译环境配置 GOPROXYIDE 设置(VS Code)一些基本

Spring Boot从main方法到内嵌Tomcat的全过程(自动化流程)

《SpringBoot从main方法到内嵌Tomcat的全过程(自动化流程)》SpringBoot启动始于main方法,创建SpringApplication实例,初始化上下文,准备环境,刷新容器并... 目录1. 入口:main方法2. SpringApplication初始化2.1 构造阶段3. 运行阶

postgresql使用UUID函数的方法

《postgresql使用UUID函数的方法》本文给大家介绍postgresql使用UUID函数的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录PostgreSQL有两种生成uuid的方法。可以先通过sql查看是否已安装扩展函数,和可以安装的扩展函数